home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / scvs / RCS / scvs,v < prev    next >
Encoding:
Text File  |  1991-12-17  |  118.9 KB  |  5,864 lines

  1. head     1.22;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    jhh:1.22; strict;
  6. comment  @# @;
  7.  
  8.  
  9. 1.22
  10. date     91.12.13.13.15.22;  author jhh;  state Exp;
  11. branches ;
  12. next     1.21;
  13.  
  14. 1.21
  15. date     91.12.12.15.41.04;  author jhh;  state Exp;
  16. branches ;
  17. next     1.20;
  18.  
  19. 1.20
  20. date     91.12.11.17.53.48;  author jhh;  state Exp;
  21. branches ;
  22. next     1.19;
  23.  
  24. 1.19
  25. date     91.11.16.18.08.03;  author jhh;  state Exp;
  26. branches ;
  27. next     1.18;
  28.  
  29. 1.18
  30. date     91.11.14.22.49.25;  author jhh;  state Exp;
  31. branches ;
  32. next     1.17;
  33.  
  34. 1.17
  35. date     91.11.13.21.39.04;  author jhh;  state Exp;
  36. branches ;
  37. next     1.16;
  38.  
  39. 1.16
  40. date     91.11.04.22.20.08;  author jhh;  state Exp;
  41. branches ;
  42. next     1.15;
  43.  
  44. 1.15
  45. date     91.11.04.21.12.46;  author jhh;  state Exp;
  46. branches ;
  47. next     1.14;
  48.  
  49. 1.14
  50. date     91.11.03.14.00.58;  author jhh;  state Exp;
  51. branches ;
  52. next     1.13;
  53.  
  54. 1.13
  55. date     91.10.31.13.08.52;  author jhh;  state Exp;
  56. branches ;
  57. next     1.12;
  58.  
  59. 1.12
  60. date     91.10.31.13.02.34;  author jhh;  state Exp;
  61. branches ;
  62. next     1.11;
  63.  
  64. 1.11
  65. date     91.10.31.12.05.01;  author jhh;  state Exp;
  66. branches ;
  67. next     1.10;
  68.  
  69. 1.10
  70. date     91.10.08.17.21.06;  author jhh;  state Exp;
  71. branches ;
  72. next     1.9;
  73.  
  74. 1.9
  75. date     91.10.08.14.53.51;  author jhh;  state Exp;
  76. branches ;
  77. next     1.8;
  78.  
  79. 1.8
  80. date     91.10.07.22.05.22;  author jhh;  state Exp;
  81. branches ;
  82. next     1.7;
  83.  
  84. 1.7
  85. date     91.09.10.23.20.03;  author jhh;  state Exp;
  86. branches ;
  87. next     1.6;
  88.  
  89. 1.6
  90. date     91.09.10.16.22.30;  author jhh;  state Exp;
  91. branches ;
  92. next     1.5;
  93.  
  94. 1.5
  95. date     91.09.05.22.27.21;  author jhh;  state Exp;
  96. branches ;
  97. next     1.4;
  98.  
  99. 1.4
  100. date     91.09.04.22.25.25;  author jhh;  state Exp;
  101. branches ;
  102. next     1.3;
  103.  
  104. 1.3
  105. date     91.09.02.12.53.04;  author jhh;  state Exp;
  106. branches ;
  107. next     1.2;
  108.  
  109. 1.2
  110. date     91.08.27.13.53.15;  author jhh;  state Exp;
  111. branches ;
  112. next     1.1;
  113.  
  114. 1.1
  115. date     91.08.21.16.18.09;  author jhh;  state Exp;
  116. branches ;
  117. next     ;
  118.  
  119.  
  120. desc
  121. @@
  122.  
  123.  
  124. 1.22
  125. log
  126. @diff and generic cvs commands didn't read the checkout args
  127. @
  128. text
  129. @#! /sprite/cmds/perl 
  130. #
  131. #   Scvs is the "Sprite Concurrent Version System", pronounced "skivies".
  132. #   It is a Perl script wrapper for cvs.  See the cvs man page for more
  133. #   details.
  134. #
  135. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.21 91/12/12 15:41:04 jhh Exp $ SPRITE (Berkeley)
  136. #
  137. # Copyright 1991 Regents of the University of California
  138. # Permission to use, copy, modify, and distribute this
  139. # software and its documentation for any purpose and without
  140. # fee is hereby granted, provided that this copyright
  141. # notice appears in all copies.  The University of California
  142. # makes no representations about the suitability of this
  143. # software for any purpose.  It is provided "as is" without
  144. # express or implied warranty.
  145. #
  146.  
  147. require "option.pl";
  148. #require "/sprite/src/lib/perl/option.pl";
  149. require "pwd.pl";
  150. require "ctime.pl";
  151. require "stat.pl";
  152.  
  153. $recurse = 1;
  154. $verbose = 0;
  155. $linkFile = "links";
  156. $debug = 0;
  157. $configFile = "SCVS.config";
  158. $argFile = "args";
  159. $modNameFile = "moduleName";
  160. $userFile = "SCVS/users";
  161. $readonly = 0;
  162.  
  163. $optFlags = $OPT_OPTIONS_FIRST | $OPT_ALLOW_CLUSTERING | $OPT_NO_SPACE;
  164.  
  165. @@options = (
  166.     $OPT_NIL, $OPT_DOC, $OPT_NIL, 
  167.     "Usage: scvs [scvs options] command [command options]",
  168.     "V", $OPT_TRUE, *verbose, "Verbose",
  169.     "D", $OPT_TRUE, *debug, "Debug",
  170.     "r", $OPT_TRUE, *readonly, "Check out files read-only",
  171.     "w", $OPT_FALSE, *readonly, "Check out files read-write (default)",
  172.     "v", $OPT_FUNC, "CvsOpt1", "Print cvs version info",
  173.     "d", $OPT_STRING, *cvsroot, "Specify cvs root directory",
  174.     "e", $OPT_FUNC, "CvsOpt1", "Specify editor to use",
  175.     "H", $OPT_FUNC, "CvsOpt1", "Print help information",
  176. );
  177. undef($cvsargs);
  178. &Opt_Parse(*ARGV, @@options, $optFlags);
  179. if ($debug) {
  180.     $verbose = 1;
  181. }
  182. $cvsCmdArgs = $cvsargs;
  183.  
  184. if ($readonly) {
  185.     $readonly = "-r";
  186. } else {
  187.     $readonly = "";
  188. }
  189.  
  190.  
  191. @@cvsCmds = ("join", "patch", "tag");
  192.  
  193. #
  194. # Global variables.
  195. #
  196. #    %moduleToRepos  maps module name to its relative path within the
  197. #            repository
  198. #    %reposToModule    reverse mapping of moduleToRepos
  199. #    %cwdToMod    maps current working directory to module name
  200. #    %cwdToRoot    maps current working directory within a module copy
  201. #            to the root dir of the module copy
  202. #
  203.  
  204. #
  205. # Config
  206. #
  207. # Find the configuration file and set up various configuration variables.
  208. #
  209. # Results: 0 if successful, 1 otherwise
  210. # Side effects: Some variables are set.
  211. #
  212.  
  213. sub Config {
  214.     local($pwd) = $ENV{'PWD'};
  215.     local($stat, $lastStat) = (0, 0);
  216.     local($tmp);
  217.     local(@@attempts);
  218.  
  219.     #
  220.     # Work our way up the directory tree looking for the config file.
  221.     #
  222.     while(! -e $configFile) {
  223.     push(@@attempts, $ENV{'PWD'});
  224.     &Chdir("..") == 0 || return 1;
  225.     &Stat(".");
  226.     $stat = $st_dev . $st_ino . $st_serverID;
  227.     last if ($stat eq $lastStat);
  228.     $lastStat = $stat;
  229.     }
  230.     if (! -e $configFile) {
  231.     printf("Couldn't find configuration file\n");
  232.     foreach $tmp (@@attempts) {
  233.         printf("Not in $tmp\n");
  234.     }
  235.     return 1;
  236.     }
  237.     open(CONFIG, "$configFile") || die("Can't open $configFile: $!\n");
  238.     while(<CONFIG>) {
  239.     next if (/^\s*#/);
  240.     if (/^cvsroot:\s+(\S+)\s*$/) {
  241.         if (!defined($cvsroot)) {
  242.         $cvsroot = $1;
  243.         }
  244.     } elsif(/^installdir:\s+(\S+)\s*$/) {
  245.         $installdir = $1;
  246.     } elsif(/^machineTypes:\s+(.*)$/) {
  247.         @@machineTypes = split(' ', $1);
  248.         printf(STDERR "machineTypes = @@machineTypes\n") if ($debug);
  249.         foreach $i (@@machineTypes) {
  250.         push(@@machineDirs, "$i.md");
  251.         }
  252.     }
  253.     }
  254.     close(CONFIG);
  255.     if (!defined($cvsroot)) {
  256.     printf("cvsroot not set in config file\n");
  257.     return 1;
  258.     }
  259.     &Chdir("$pwd") == 0 || return 1;
  260.     return 0;
  261. }
  262.  
  263. #
  264. # PackCmd($command, @@dirs)
  265. #
  266. # Runs a Pack or Unpack command on each of the directories in the list.
  267. #
  268. # Results: 0 if successful, 1 otherwise
  269. #
  270. # Side effects:  The link file is modified.
  271. #
  272.  
  273. sub PackCmd {
  274.     local($command) = shift;
  275.     local(@@dirs) = @@_;
  276.     local($status) = 0;
  277.     local($pwd) = $ENV{'PWD'};
  278.  
  279.     if ($#dirs < $[) {
  280.     push(@@dirs, '.');
  281.     }
  282.     foreach $dir (@@dirs) {
  283.     &Chdir($dir) == 0 || return 1; 
  284.     if ($command eq "pack") {
  285.         $status = &Pack($dir);
  286.     } else {
  287.         $status = &Unpack($dir);
  288.     }
  289.     if ($status) {
  290.         return $status;
  291.     }
  292.     &Chdir($pwd) == 0 || return 1; 
  293.     }
  294. }
  295. #
  296. # Pack($path)
  297. #
  298. # Finds all symbolic links in the current directory and puts them in the
  299. # link file.  The links are stored in alphabetical
  300. # order.  If $recurse is non-zero, Pack will call itself to recurse on
  301. # subdirectories.
  302. #
  303. # Results: 0 if successful, 1 otherwise
  304. #
  305. # Side effects: The link file is modified.
  306. #
  307.  
  308. sub Pack {
  309.     local($path) = shift;
  310.     local($addDir) = 0;
  311.     local($addFile) = 0;
  312.     local(%links);
  313.     local($link);
  314.  
  315.     #
  316.     # Don't pack SCVS subdirectories.
  317.     #
  318.     if ($path =~ m|.*/SCVS|) {
  319.     return 0;
  320.     }
  321.     printf(STDERR "Packing $path\n") if ($debug);
  322.     $addDir = (-d "SCVS") ? 0 : 1;
  323.     $addFile = (-f "SCVS/$linkFile") ? 0 : 1;
  324.     opendir(THISDIR, ".") || return &Error(1, "Opendir of $path failed: $!\n");
  325.     foreach $link (grep(-l, readdir(THISDIR))) {
  326.     printf(STDERR "$link\n") if ($debug);
  327.     $links{$link} = readlink($link);
  328.     }
  329.     close(THISDIR);
  330.     if (defined(%links) || (!$addFile)) {
  331.     if ($addDir) {
  332.         mkdir("SCVS", 0770) ||
  333.         return &Error(1, "Mkdir of SCVS failed: $!\n");
  334.     }
  335.     if (open(PACK, ">SCVS/$linkFile") == 0) {
  336.         printf("Can't open $linkFile: $!\n");
  337.         $status = 1;
  338.         last;
  339.     }
  340.     printf(PACK 
  341.         "# This file is used by scvs and contains symbolic link\n");
  342.     printf(PACK 
  343.         "# information.  Each line is of the form \"link target\"\n");
  344.     printf(PACK "# \$Header\n");
  345.     foreach $link (sort keys %links) {
  346.         printf(PACK "%-24s %s\n", $link, $links{$link});
  347.     }
  348.     close(PACK);
  349.     if ($addFile && (-e "CVS.adm")) {
  350.         if ($addDir) {
  351.         &System("cvs -d $cvsroot $readonly add SCVS");
  352.         }
  353.         &System(
  354.         "cvs -d $cvsroot $readonly add -m\"scvs links\" SCVS/$linkFile");
  355.     }
  356.     } 
  357.     if ($recurse) {
  358.     $status = &AllSubdirs($path, "Pack");
  359.     }
  360.     return $status;
  361. }
  362.  
  363. #
  364. # Unpack($path)
  365. #
  366. # Reads the link file in the current directory and creates symbolic links
  367. # from its contents. If recurse is non-zero, Unpack will call itself to 
  368. # recurse on subdirectories.
  369. #
  370. # Results: 0 if successful, 1 otherwise
  371. #
  372. # Side effects: Symbolic links may be created in the current directory
  373. #
  374. sub Unpack {
  375.     local($path) = shift;
  376.     local($status) = 0;
  377.     local(@@links);
  378.     local($minor);
  379.  
  380.     printf(STDERR "Unpacking $path\n") if ($debug);
  381.     if (-f "SCVS/$linkFile") {
  382.     #
  383.     # Remove any links that have been deleted.
  384.     #
  385.     opendir(THISDIR, ".") || 
  386.         return &Error(1, "Opendir of $path failed: $!\n"); 
  387.     @@links = grep((-l), readdir(THISDIR));
  388.     close(THISDIR);
  389.     if ($#links >= $[) {
  390.         local($owd) = $ENV{'PWD'};
  391.         printf(STDERR "Found links @@links\n") if ($debug);
  392.         &Chdir("SCVS") == 0 || return 1;
  393.         open(UNPACK, 
  394.         "cvs -d $cvsroot $readonly status $linkFile |") ||
  395.         return &Error(1, 
  396.             "Can't get status for $path/SCVS/$linkFile: $!\n");
  397.         while(<UNPACK>) {
  398.         if (/^RCS:\s+(\d+)\.(\d+)/) {
  399.             $minor = $2 - 1;
  400.             $version = "-r $1.$minor";
  401.             last;
  402.         }
  403.         }
  404.         close(UNPACK);
  405.         printf(STDERR "Rcs version is $version\n") if ($debug);
  406.         if (open(UNPACK, 
  407.             "cvs -d $cvsroot $readonly diff $version $linkFile |")) {
  408.         &Chdir("$owd") == 0 || return 1;
  409.         while(<UNPACK>) {
  410.             if (/^<\s+(\S+)/) {
  411.             if (grep(/^$1$/, @@links)) {
  412.                 printf("D $1\n");
  413.                 unlink("$1");
  414.             }
  415.             }
  416.         }
  417.         close(UNPACK);
  418.         } else {
  419.         &Chdir("$owd") == 0 || return 1;
  420.         }
  421.     }
  422.     open(UNPACK, "SCVS/$linkFile") || 
  423.         return &Error(1, "Open of SCVS/$linkFile failed: $!\n");
  424.     while(<UNPACK>) {
  425.         next if (/^#/);
  426.         if (/(\S+)\s+(\S+)/) {
  427.         ($link, $value) = ($1, $2);
  428.         #
  429.         # Sometimes the link files have bogus lines that we should
  430.         # skip over.
  431.         #
  432.         next if (/^[*]/);
  433.         if (/^[><]/) {
  434.             printf("Links file was merged.\n");
  435.             printf("Fix it and do unpack by hand\n");
  436.             return 1;
  437.         }
  438.         if (-l $link) {
  439.             $old = readlink($link);
  440.             if ($old ne $value) {
  441.             printf(
  442.             "Changing $link -> $value, instead of -> $old\n");
  443.             unlink($link);
  444.             } else {
  445.             next;
  446.             }
  447.         } elsif (-e $link) {
  448.             printf("File $link already exists.\n");
  449.             $status = 1;
  450.             next;
  451.         } elsif ($verbose) {
  452.             printf("Creating: $link -> $value\n");
  453.         }
  454.         if (symlink($value, $link) == 0) { 
  455.             printf("Can't create link from $link to $value: $!");
  456.             $status = 1;
  457.         }
  458.         }
  459.     }
  460.     close(UNPACK);
  461.     }
  462.     if ($recurse) {
  463.     $status = &AllSubdirs($path, "Unpack");
  464.     }
  465.     return $status;
  466. }
  467.  
  468. #
  469. # Repository(module)
  470. #
  471. # Finds the pathname of the repository directory for the given module.
  472. #
  473. # Results: The pathname
  474. #
  475. # Side effects: 
  476. #
  477.  
  478. sub Repository {
  479.     local($tmp);
  480.     $tmp = &ReadFile("$_[0]/CVS.adm/Repository", 1);
  481.     if (defined($tmp)) {
  482.     chop($tmp);
  483.     return "$cvsroot/$tmp"; 
  484.     }
  485.     return undef;
  486. }
  487.  
  488. #
  489. # Prune($path)
  490. #
  491. # Removes the given directory if it is empty (no user files or subdirectories).
  492. # Recurses on subdirectories.
  493. #
  494. # Results: 0 if successful, 1 otherwise
  495. #
  496. # Side effects: The directory or its subdirectories may be removed.
  497. #
  498.  
  499. sub Prune {
  500.     local($path) = shift;
  501.     local($module) = shift;
  502.     local($i);
  503.     local($status) = 0;
  504.     local($tail) = substr($path, rindex($path, '/') + 1);
  505.     local(@@contents);
  506.     local($cwd);
  507.  
  508.     if ($tail eq "SCVS") {
  509.     return 0;
  510.     }
  511.     print "Pruning $path\n" if ($debug);
  512.     $status = &AllSubdirs($path, "Prune", $module);
  513.     if ($status) {
  514.     return $status;
  515.     }
  516.     #
  517.     # Don't prune empty .md directories of valid machine types.
  518.     #
  519.     if ($tail eq ".") {
  520.     $tail = substr($ENV{'PWD'}, rindex($ENV{'PWD'}, '/') + 1);
  521.     }
  522.     if ($tail =~ /(.*)\.md/) {
  523.     if (grep(/^$1$/, @@machineTypes)) {
  524.         printf(STDERR "Skipping $tail ($1)\n") if ($debug);
  525.         return 0;
  526.     }
  527.     }
  528.     #
  529.     # Don't prune the root directory of the module even if it's empty.
  530.     #
  531.     $cwd = $ENV{'PWD'};
  532.     printf("$module $cwd\n") if ($debug);
  533.     if (substr($cwd, rindex($cwd, '/') + 1) eq "$module") {
  534.     return 0;
  535.     }
  536.     opendir(THISDIR, ".") || 
  537.     return &Error(1, "Opendir of $path failed: $!\n"); 
  538.     @@contents = grep((-f) || ((!/\./) && ($_ ne 'CVS.adm') && 
  539.             ($_ ne 'SCVS')), readdir(THISDIR));
  540.     close(THISDIR);
  541.     if ($#contents < $[) {
  542.     print "Prune: chdir to ..\n" if ($debug);
  543.     &Chdir("..") == 0 || return 1;
  544.     print "Prune: deleting $tail\n" if ($debug);
  545.     &System("rm -rf $tail");
  546.     }
  547.     return 0;
  548. }
  549.  
  550. #
  551. # CreateRootLinks($path, $root)
  552. #
  553. # Creates symbolic links called "root" in the SCVS directories that point
  554. # to the root directory for the module copy.
  555. #
  556. # Results: 0 if successful, 1 otherwise
  557. #
  558. # Side effects: 
  559. #
  560.  
  561. sub CreateRootLinks {
  562.     local($root) = "../$_[1]";
  563.     if ((-e "SCVS") && !(-e "SCVS/root")) {
  564.     symlink($root, "SCVS/root") || 
  565.         return &Error(1, "Symlink $root, SCVS/root failed: $!\n"); 
  566.     }
  567.     return &AllSubdirs($_[0], "CreateRootLinks", $root);
  568. }
  569.  
  570.  
  571. #
  572. # CvsOpt1($optString, $nextArg)
  573. #
  574. # Appends $optString to $cvsargs.
  575. #
  576. # Results: 0 
  577. #
  578. # Side effects: None
  579. #
  580. sub CvsOpt1 {
  581.     printf("CvsOpt1 @@_\n") if ($debug);
  582.     $cvsargs .= "$_[0] ";
  583.     return 0;
  584. }
  585.  
  586. #
  587. # CvsOpt2($optString, $nextArg)
  588. #
  589. # Appends $optString and $nextArg to $cvsargs.
  590. #
  591. # Results: 1
  592. #
  593. # Side effects: None
  594. #
  595. sub CvsOpt2 {
  596.     printf("CvsOpt2 @@_\n") if ($debug);
  597.     $cvsargs .= "$_[0] \"$_[1]\" ";
  598.     return 1;
  599. }
  600.  
  601.  
  602. #
  603. # Checkout(@@modules)
  604. #
  605. # Checks out modules.  "cvs co" is used to make a copy of the module. 
  606. # Unpack is used to unpack symbolic links.  
  607. # The current user name is added to the SCVS.users
  608. # file and a list of any other users with a copy of the module are 
  609. # printed.  Any options passed to "cvs co" are stored in the SCVS/args
  610. # file to be used on subsequent updates.
  611. #
  612. # Results: 0 if successful, 1 otherwise
  613. #
  614. # Side effects: A subdirectory is created for each module.
  615. #
  616.  
  617. sub Checkout {
  618.     local(@@modules) = @@_;
  619.     local($buffer, $i,$repos, $user, $date, %count, %dates);
  620.     local($found, $name);
  621.     local($prune) = 1;
  622.     local($personal) = 0;
  623.     local($args);
  624.     local(@@mine, %others);
  625.     local(@@options) = ( 
  626.     "l", $OPT_FALSE, *recurse, "Don't recurse.",
  627.     "P", $OPT_FALSE, *prune, "Don't prune empty directories.",
  628.     "i", $OPT_TRUE, *personal, "Deviation from standard source tree",
  629.     "f", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  630.     "c", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  631.     "Q", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  632.     "q", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  633.     "f", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  634.     "n", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  635.     "p", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  636.     "r", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  637.     "D", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  638.      );
  639.  
  640.     undef($cvsargs);
  641.     &Opt_Parse(*modules, @@options, $optFlags);
  642.     $args = $cvsargs;
  643.     if (@@errors = grep(/^-/, @@modules)) {
  644.     print("Unknown options \"@@errors\" to checkout command\n");
  645.     return 1;
  646.     }
  647.  
  648.     # Put together the "cvs co" command.
  649.  
  650.     $buffer = "cvs -d $cvsroot $cvsCmdArgs $readonly co $args";
  651.  
  652.     if ($args =~ /-c/) {
  653.     &System("$buffer");
  654.     return 0;
  655.     }
  656.    if (($args =~ /-r/) || ($args =~ /-D/)) {
  657.     $buffer .= "-f ";
  658.     }
  659.     if ($#modules < $[) {
  660.     print("scvs co requires a list of modules\n");
  661.     return 1;
  662.     }
  663.     $status = &Lock("r", @@modules);
  664.     if ($status) {
  665.     return $status;
  666.     }
  667.     $user = getlogin;
  668.     print "@@modules\n" if ($debug);
  669.  
  670. module:
  671.     foreach $i (@@modules) {
  672.     local($pwd) = $ENV{'PWD'};
  673.  
  674.     @@mine = ();
  675.     %others = ();
  676.     printf("Checking out $i\n") if ($debug);
  677.     # Perform the "cvs co".
  678.  
  679.     &System("$buffer $i");
  680.  
  681.     # Store the "cvs co" arguments in the info file.
  682.  
  683.     if (! -d "$i/SCVS") {
  684.         if (!mkdir("$i/SCVS", 0770)) {
  685.         $status = &Error(1, "Mkdir of $i/SCVS failed: $!\n");
  686.         next module;
  687.         }
  688.     }
  689.     if (!open(CO, ">$i/SCVS/$argFile")) {
  690.         $status = &Error(1, "Open of $i/SCVS/$argFile failed: $!\n");
  691.         next module;
  692.     }
  693.     print(CO "# This file contains the arguments given when this\n");
  694.     print(CO "# module was checked out.\n");
  695.     print(CO "$cvsCmdArgs $readonly\n");
  696.     printf(CO "$args %s\n", $prune ? "-p" : " ");
  697.     close(CO);
  698.  
  699.     &Chdir($i) == 0 || return 1; 
  700.  
  701.     # Unpack the module.
  702.     &Unpack($i) == 0 || return &Error("Unpack of $i failed\n");
  703.  
  704.     # Prune any empty directories in the module.
  705.     if ($prune) {
  706.         &Prune($i, $i) == 0 || return &Error(1, "Prune of $i failed\n");
  707.     }
  708.  
  709.     # Create the "root" symbolic links in the SCVS directories.
  710.     &CreateRootLinks(".") == 0 || 
  711.         return &Error("CreateRootLinks of $i failed\n");
  712.     &Chdir($pwd) == 0 || return 1; 
  713.  
  714.     # See if any other users have a copy of the module, and add our
  715.     # own entry.
  716.  
  717.     $repos = &Repository($i);
  718.     next module if (!defined($repos));
  719.     $date = &ctime(time);
  720.     open(CO2, ">$repos/$tmpfile") ||
  721.         return &Error(1, "Open of $repos/$tmpfile failed: $!\n");
  722.     if (-e "$repos/$userFile") {
  723.         local($copy) = 0;
  724.         open(CO1, "$repos/$userFile") ||
  725.         return &Error(1, "Open of $repos/$userFile failed: $!\n");
  726.         while(<CO1>) {
  727.         $copy = 0;
  728.         next if (/^#/);
  729.         if (/^$user\s+([\w\/\.]+)\s+(.*)/) {
  730.             if ($1 eq "$pwd/$i") {
  731.             $copy = 1;
  732.             } else {
  733.             $found = 1;
  734.             push(@@mine, $_);
  735.             }
  736.         } elsif (/^(\S+)\s+([\w\/\.]+)\s+(.*)/) {
  737.             $others{$1} = $3;
  738.         }
  739.         }
  740.         continue {
  741.         if (!$copy) {
  742.             print CO2 $_;
  743.         }
  744.         }
  745.         close(CO1);
  746.     } else {
  747.         printf(CO2 "# List of users with copies of this module.\n");
  748.     }
  749.     if ($#mine >= $[) {
  750.         printf("\nYou also have these copies of the $i module:\n");
  751.         print join("\n", @@mine);
  752.     }
  753.     printf(CO2 "$user $pwd/$i %s", &ctime(time));
  754.     close(CO2);
  755.     if (!$personal) {
  756.         if (!rename("$repos/$tmpfile", "$repos/$userFile")) {
  757.         printf(
  758.           "Rename of $repos/$tmpfile to $repos/$userFile failed:$!\n");
  759.         unlink("$repos/$tmpfile");
  760.         next module;
  761.         }
  762.     } else {
  763.         unlink("$repos/$tmpfile");
  764.     }
  765.     if (!$personal && defined(%others)) {
  766.         printf("\nThe following users have copies of the $i module:\n"); 
  767.         while(($name, $date) = each(%others)) {
  768.         printf("$name $date\n");
  769.         }
  770.     }
  771.     }
  772.     return 0;
  773. }
  774.  
  775. #
  776. # UnlockCmd(@@ARGV)
  777. #
  778. # Parse arguements, then call Unlock to do the dirty work. 
  779. #
  780. # Results: 0 if successful, 1 otherwise
  781. #
  782. # Side effects: 
  783. #
  784. sub UnlockCmd {
  785.     local(@@args) = @@_;
  786.     local($all) = 0;
  787.     local($status) = 0;
  788.     local(@@options) = (
  789.     "a", $OPT_TRUE, *all, "Remove everybody's locks",
  790.     );
  791.     &Opt_Parse(*args, @@options, $optFlags);
  792.     if (@@errors = grep(/^-/, @@args)) {
  793.     print("Unknown options \"@@errors\" to unlock command\n");
  794.     return 1;
  795.     }
  796.     $status = &Unlock($all,@@args);
  797.     return $status;
  798. }
  799.  
  800.  
  801. #
  802. # Unlock($allusers, @@modules)
  803. #
  804. # Remove the locks for a list of modules.  
  805. #
  806. # Results: 0 if successful, 1 otherwise
  807. #
  808. # Side effects: 
  809. #
  810.  
  811. sub Unlock {
  812.     local($allusers) = shift;
  813.     local(@@modules) = @@_;
  814.     local($cvsdir, $i, $lock);
  815.     local($status) = 0;
  816.     local($user) = getlogin;
  817.  
  818.     print("Unlock $allusers @@modules\n") if ($debug);
  819.     if ($#modules < $[) {
  820.     push(@@modules, ".");
  821.     }
  822. module:
  823.     foreach $i (@@modules) {
  824.     if ($i eq ".") {
  825.         $i = &GetModuleName();
  826.         if (!defined($i)) {
  827.         $status = 1;
  828.         next module;
  829.         }
  830.     }
  831.     if (!defined($moduleToRepos{$i})) {
  832.         printf(STDERR "Module $i does not exist.\n");
  833.         $status = 1;
  834.         next module;
  835.     }
  836.     $cvsdir = "$cvsroot/$moduleToRepos{$i}/SCVS";
  837.     $lock = "$cvsdir/locks";
  838.     if (!-e $lock) {
  839.         next module;
  840.     }
  841.     if ($allusers) {
  842.         if (!unlink($lock)) {
  843.         printf("Can't remove lock file $lock: $!\n");
  844.         }
  845.         next module;
  846.     }
  847.     if (!open(UNLOCK1, "$lock")) {
  848.         print("Open of $lock failed: $!\n");
  849.         next module;
  850.     }
  851.     if (!open(UNLOCK2, ">$cvsdir/$tmpfile")) {
  852.         print("Open of $cvsdir/$tmpfile failed: $!\n");
  853.         next module;
  854.     }
  855.     flock(UNLOCK1, 2) || 
  856.         return &Error(1, "Flock(2) of $lock failed: $!\n");
  857.  
  858.     while(<UNLOCK1>) {
  859.         ($type, $name) = split(' ');
  860.         if ($name ne $user) {
  861.         print(UNLOCK2 $_);
  862.         }
  863.     }
  864.     close(UNLOCK2);
  865.     if (!rename("$cvsdir/$tmpfile", "$lock")) {
  866.         printf(
  867.           "Rename of $cvsdir/$tmpfile to $lock failed:$!\n");
  868.         unlink("$cvsdir/$tmpfile");
  869.         next module;
  870.     }
  871.     }
  872.     return $status;
  873. }
  874.  
  875. #
  876. # LockCmd(@@ARGV)
  877. #
  878. # Parse any options then call Lock to do all the work.
  879. #
  880. # Results: 0 if successful, 1 otherwise
  881. #
  882. # Side effects: The lock files in the modules are updated.
  883. #
  884.  
  885. sub LockCmd {
  886.     local(@@args) = @@_;
  887.     local($write) = 1;
  888.     local($status) = 0;
  889.     local(@@options) = (
  890.     "w", $OPT_TRUE, *write, "Write (exclusive) lock",
  891.     "r", $OPT_FALSE, *write, "Read (shared) lock",
  892.     );
  893.     print("LockCmd @@args\n") if ($debug);
  894.     &Opt_Parse(*args, @@options, $optFlags);
  895.     if (@@errors = grep(/^-/, @@args)) {
  896.     print("Unknown options \"@@errors\" to lock command\n");
  897.     return 1;
  898.     }
  899.     $status = &Lock($write ? "w" : "r", @@args);
  900.     undef(@@locks);
  901.     return $status;
  902. }
  903.  
  904.  
  905. #
  906. # Lock($type, @@modules)
  907. #
  908. # Make sure the modules are unlocked, and lock them.  Any modules that
  909. # we lock are put in the @@lock array.  
  910. #
  911. # Results: 0 if successful, 1 otherwise
  912. #
  913. # Side effects: Lock files are created in the modules.
  914. #
  915.  
  916. sub Lock {
  917.     local($type) = shift;
  918.     local(@@dirs) = @@_;
  919.     local($cvsdir);
  920.     local($status) = 0;
  921.     local($i, $name);
  922.     local(@@mylocks);
  923.     local($user) = getlogin;
  924.     local(@@lockFiles);
  925.     local($prevType);
  926.     local($prevName);
  927.     local($prevDate);
  928.     local(@@prevLocks);
  929.     local($lock);
  930.     local(@@modules);
  931.  
  932.     print("Lock $type @@dirs\n") if ($debug);
  933.     if ($#dirs < $[) {
  934.     @@dirs = (".");
  935.     }
  936. dir:
  937.     foreach $i (@@dirs) {
  938.     #
  939.     # If the directory doesn't exist then assume we've been given
  940.     # a module name instead.
  941.     #
  942.     if (! -d "$i") {
  943.         $module = $i;
  944.     } else {
  945.         $module = &GetModuleName($i);
  946.         if (!defined($module)) {
  947.         printf("Can't find module name for directory \"$i\"\n"); 
  948.         $status = 1;
  949.         next dir;
  950.         }
  951.     }
  952.     $repos = $moduleToRepos{$module};
  953.     if (!defined($repos)) {
  954.         printf(STDERR "$i module does not exist.\n");
  955.         $status = 1;
  956.         next dir;
  957.     }
  958.     $cvsdir = "$cvsroot/$repos/SCVS";
  959.     $lock = "$cvsdir/locks";
  960.     print("Cvsdir = $cvsdir\n") if ($debug);
  961.     if (-f "$lock") {
  962.         print("Opening $lock\n") if ($debug);
  963.         open(LOCK1, "$lock") || 
  964.         return &Error(1, "Open of $lock failed: $!\n");
  965.         flock(LOCK1, 2) || 
  966.         return &Error(1, "Flock(2) of $lock failed: $!\n");
  967.         while(<LOCK1>) {
  968.         ($prevType, $prevName) = split(' ');
  969.         if ($prevName eq $user) {
  970.             if ($prevType ne $type) {
  971.             return &Error(1, "$i already locked:\n$_");
  972.             } else {
  973.             close(LOCK1);
  974.             next dir;
  975.             }
  976.         } else {
  977.             if (($prevType eq "r") && ($type eq "w")) {
  978.             return &Error(1, "$i already locked:\n$_");
  979.             } elsif ($prevType eq "w") {
  980.             return &Error(1, "$i already locked:\n$_");
  981.             }
  982.         }
  983.         push(@@prevLocks, $_);
  984.         }
  985.     }
  986.     open(LOCK2, ">$cvsdir/$tmpfile") ||
  987.         return &Error(1, "Open of $cvsdir/$tmpfile failed: $!\n");
  988.     foreach $i (@@prevLocks) {
  989.         print(LOCK2 "$i");
  990.     }
  991.     printf(LOCK2 "$type $user %s", &ctime(time));
  992.     close(LOCK2);
  993.     if (!rename("$cvsdir/$tmpfile", "$lock")) {
  994.         printf(
  995.           "Rename of $cvsdir/$tmpfile to $lock failed:$!\n");
  996.         unlink("$cvsdir/$tmpfile");
  997.         return 1;
  998.     }
  999.     push(@@mylocks, $module);
  1000.     close(LOCK1);
  1001.     }
  1002.     if (($status) && ($#mylocks >= $[)) {
  1003.     if (&Unlock(0, @@mylocks)) {
  1004.         return &Error(1, "Can't clean up in LockCmd\n");
  1005.     }
  1006.     }
  1007.     push(@@locks, @@mylocks);
  1008.     return $status;
  1009. }
  1010.  
  1011. #
  1012. # UpdateCmd($lock, @@names)
  1013. #
  1014. # Update modules.  If the arguments are a list of subdirectories then
  1015. # we chdir to each of them and run "cvs update".  If the arguments are
  1016. # a list of files then we pass them to cvs.  If no files or directories
  1017. # are specified then we update the current directory.  The arguments
  1018. # for update are retrieved from the SCVS/args file.
  1019. #
  1020. # Results: 0 if successful, 1 otherwise
  1021. #
  1022. # Side effects: 
  1023. #
  1024.  
  1025. sub UpdateCmd {
  1026.     local($lock) = shift;
  1027.     local(@@names) = @@_;
  1028.     local(%dirs);
  1029.     local($buffer, $i);
  1030.     local($found, $name);
  1031.     local($module);
  1032.     local($owd);
  1033.     local($tmp);
  1034.     local($prune);
  1035.     local($buildDirs) = 1;
  1036.     local($args);
  1037.     local($module);
  1038.     local(@@targs);
  1039.     local($quiet) = 0;
  1040.     local(@@options) = ( 
  1041.     "B", $OPT_FALSE, *buildDirs, "Don't create new directories.",
  1042.     "l", $OPT_FALSE, *recurse, "Don't recurse on subdirs",
  1043.     "Q", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1044.     "q", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1045.     "f", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1046.     "n", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1047.     "p", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1048.     "d", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1049.     "r", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  1050.     "D", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  1051.     );
  1052.     print("UpdateCmd: @@names\n") if ($debug);
  1053.     undef($cvsargs);
  1054.     &Opt_Parse(*names, @@options, $optFlags);
  1055.     $args = $cvsargs;
  1056.     if (@@errors = grep(/^-/, @@names)) {
  1057.     print("Unknown options \"@@errors\" to update command\n");
  1058.     return 1;
  1059.     }
  1060.  
  1061.     print("UpdateCmd in $ENV{'PWD'}\n") if ($debug);
  1062.  
  1063.     # Put together the "cvs update" command.
  1064.  
  1065.     if ($buildDirs) {
  1066.     $args .= "-d ";
  1067.     }
  1068.     if (! $recurse) {
  1069.     $args .= "-l ";
  1070.     }
  1071.     if ($args =~ /-q|-Q/) {
  1072.     $quiet = 1;
  1073.     } 
  1074.     $buffer = "cvs -d $cvsroot $cvsCmdArgs ";
  1075.  
  1076.     %dirs = &ProcessNames(1, @@names);
  1077.  
  1078.     #
  1079.     # Lock the modules.
  1080.     #
  1081.     if ($lock) {
  1082.     $status = &Lock("r", keys(%dirs)); 
  1083.     if ($status) {
  1084.         return $status;
  1085.     }
  1086.     }
  1087.     $owd = $ENV{'PWD'};
  1088. dir: 
  1089.     while (($i, $files) = each(%dirs)) {
  1090.     if (! $quiet) {
  1091.         print("$i\n");
  1092.     }
  1093.     $prune = 0;
  1094.     &Chdir($i) == 0 || return 1; 
  1095.     @@targs = &GetCheckoutArgs();
  1096.     $targs[1] =~ s/-p//g;
  1097.     $tmp = "$buffer $targs[0] update $args $targs[1] $files";
  1098.     &System($tmp);
  1099.     if (&Unpack($i)) {
  1100.         printf(STDERR "Unpack of $i failed.\n");
  1101.         $status = 1;
  1102.     }
  1103.     if ($prune) {
  1104.         $module = &GetModuleName();
  1105.         if (&Prune($i, $module)) {
  1106.         printf(STDERR "Prune of $i failed.\n");
  1107.         $status = 1;
  1108.         }
  1109.     }
  1110.     &Chdir($owd) == 0 || return 1; 
  1111.     }
  1112.     return $status;
  1113. }
  1114.  
  1115. #
  1116. # Changed($path)
  1117. #
  1118. # Use the "cvs info" command to see if the contents of the current directory
  1119. # or its subdirectories have been changed by the user.  The modified
  1120. # parameter is set to 1 if they have been.
  1121. #
  1122. # Results: 0 if successful, 1 otherwise; 0 if not modified, 1 otherwise
  1123. #
  1124. # Side effects: 
  1125. #
  1126. sub Changed {
  1127.     local($path) = shift;
  1128.     local($modified) = 0;
  1129.     local($status) = 0;
  1130.     if (!-d "CVS.adm") {
  1131.     return 0;
  1132.     }
  1133.     open(CHG, "cvs -d $cvsroot info |") ||
  1134.     return &Error(1, "Can't do cvs info on $path: $!\n");
  1135.     while (<CHG>) {
  1136.     if (/^[MC]\s+(\S+)/) {
  1137.         printf("$path/$1 has been modified\n");
  1138.         $modified = 1;
  1139.     } elsif(/^A\s+(\S+)/) {
  1140.         printf("$path/$1 has been added\n");
  1141.         $modified = 1;
  1142.     } elsif(/^R\s+(\S+)/) {
  1143.         printf("$path/$1 has been deleted\n");
  1144.         $modified = 1;
  1145.     }
  1146.     }
  1147.     close(CHG);
  1148.     ($status, @@results) = &AllSubdirs($path, "Changed");
  1149.     if ($status) {
  1150.     return $status;
  1151.     }
  1152.     while ($#results >= $[) {
  1153.     local($substatus) = shift(@@results);
  1154.     local($submod) = shift(@@results);
  1155.     if ($substatus) {
  1156.         $status = 1;
  1157.     }
  1158.     if ($submod) {
  1159.         $modified = 1;
  1160.     }
  1161.     }
  1162.     return ($status, $modified);
  1163. }
  1164.  
  1165. #
  1166. # DoneCmd(@@modules)
  1167. #
  1168. # Process the "done" command.  The user is deleted from the list of users
  1169. # for each module.  If the -d flag is specified then the snapshot is
  1170. # deleted as well.  If the user has made changes to the snapshot the user
  1171. # is warned before the "done" command is completed.
  1172. #
  1173. # Results: 0 if successful, 1 otherwise
  1174. #
  1175. # Side effects: 
  1176. #
  1177. sub DoneCmd {
  1178.     local(@@modules) = @@_;
  1179.     local($status) = 0;
  1180.     local($i);
  1181.     local($me) = getlogin;
  1182.     local($pwd) = $ENV{'PWD'};
  1183.     local($repos, $found);
  1184.     local($delete);
  1185.     local($modified);
  1186.     local(@@options) = (
  1187.     "d", $OPT_TRUE, *delete, "Delete module",
  1188.     );
  1189.  
  1190.     $recurse = 1;
  1191.     undef($cvsargs);
  1192.     &Opt_Parse(*modules, @@options, $optFlags);
  1193.     if ($#modules < $[) {
  1194.     return &Error(1, "Done command requires a list of modules\n");
  1195.     }
  1196.     if (@@errors = grep(/^-/, @@modules)) {
  1197.     print("Unknown options \"@@errors\" to done command\n");
  1198.     return 1;
  1199.     }
  1200.     # Make sure all the modules are unlocked, then lock them.
  1201.     $status = &Lock("r",@@modules); 
  1202.     if ($status) {
  1203.     return $status;
  1204.     }
  1205. module:
  1206.     foreach $i (@@modules) {
  1207.     $ok = 0;
  1208.     if (! -d $i) {
  1209.         if (substr($i, 0, 1) eq "/") {
  1210.         $i = substr($i, rindex($i, '/') + 1);
  1211.         } else {
  1212.         printf("Directory $i not found.\n");
  1213.         next module;
  1214.         }
  1215.     } else {
  1216.         &Chdir($i) == 0 || return 1; 
  1217.         ($status, $modified) = &Changed($i);
  1218.         if ($status) {
  1219.         printf(STDERR 
  1220.             "Unable to determine if $i module has changed.\n");
  1221.         $modified = 1;
  1222.         }
  1223.         if ($modified == 1) {
  1224.         printf("Do you wish to continue? [y/n] ");
  1225. prompt:
  1226.         while(1) {
  1227.             $answer = <STDIN>;
  1228.             chop($answer);
  1229.             last prompt if ($answer eq "y");
  1230.             next module if ($answer eq "n");
  1231.             printf("Please answer with \"y\" or \"n\": ");
  1232.         }
  1233.         } elsif ($modified == 1) {
  1234.         next module;
  1235.         }
  1236.     }
  1237.  
  1238.     # Update the user file.
  1239.     $repos = &Repository(".");
  1240.     next module if (!defined($repos));
  1241.     if (!open(DONE1, "$repos/$userFile")) {
  1242.         printf("Module $i is not checked out\n");
  1243.         next module;
  1244.     }
  1245.     if (!open(DONE2, ">$repos/$tmpfile")) {
  1246.         printf("Can't open $repos/$tmpfile: $!\n");
  1247.         $status = 1;
  1248.         next module;
  1249.     }
  1250.     $me = getlogin;
  1251.     $found = 0;
  1252.     while (<DONE1>) {
  1253.         if (/^$me\s+([\w\/\.]+)\s+(.*)/) {
  1254.         if ($1 eq "$pwd/$i") {
  1255.             $found = 1;
  1256.             next;
  1257.         }
  1258.         }
  1259.         print DONE2 $_;
  1260.     }
  1261.     close(DONE1);
  1262.     close(DONE2);
  1263.     if (!$found) {
  1264.         printf("Module $i is not checked out\n");
  1265.         next module;
  1266.     }
  1267.     if (!rename("$repos/$tmpfile", "$repos/$userFile")) {
  1268.         printf("Rename of $repos/$tmpfile to $repos/$userFile failed:$!\n");
  1269.         unlink("$repos/$tmpfile");
  1270.         next module;
  1271.     }
  1272.     $ok = 1;
  1273.     }
  1274.     continue {
  1275.     &Chdir($pwd) == 0 || return 1; 
  1276.     if ($ok && $delete) {
  1277.         &System("rm -rf $i");
  1278.         if ($?) {
  1279.         printf("Delete of $i failed: $?\n");
  1280.         }
  1281.     }
  1282.     }
  1283.     return $status;
  1284. }
  1285.  
  1286. #
  1287. # AllSubdirs(path, routine, args)
  1288. #
  1289. # Call a routine for each subdirectory of the current directory. The
  1290. # current working directory is changed to the subdirectory before the 
  1291. # routine is called, and the path is modified to reflect this change.
  1292. # The path is passed to the routine when it is called. The routine is
  1293. # called for all subdirectories even if one returns an non-zero status,
  1294. # although this function will then return a non-zero status.
  1295. # Any additional arguments for the routine are passed after the path
  1296. # argument.
  1297. #
  1298. # Results: 0 if successful, 1 if the routine returned non-zero for any
  1299. #         of the subdirectories.
  1300. #
  1301. # Side effects: 
  1302. #
  1303. sub AllSubdirs {
  1304.     local($path) = shift;
  1305.     local($routine) = shift;
  1306.     local($pwd) = $ENV{'PWD'};
  1307.     local($substatus);
  1308.     local($dir);
  1309.     local(@@results);
  1310.     local(@@status);
  1311.     local(@@subdirs);
  1312.  
  1313.     printf(STDERR "AllSubdirs of $routine on $pwd\n") if ($debug);
  1314.     opendir(THISDIR, ".") || 
  1315.     return &Error(1, "Opendir of $path failed: $!\n"); 
  1316.     @@subdirs = grep((-d) && (!/^\./) && (! -l) && ($_ ne 'CVS.adm'), 
  1317.             readdir(THISDIR));
  1318.     print("AllSubdirs: @@subdirs\n") if ($debug);
  1319.     close(THISDIR);
  1320.     print "@@subdirs\n****\n" if ($debug); 
  1321.     foreach $dir (@@subdirs) {
  1322.     printf("\t$dir\n") if ($debug);
  1323.     &Chdir($dir) == 0 || return 1; 
  1324.     push(@@results, &$routine($path . "/$dir", @@_));
  1325.     &Chdir($pwd) == 0 || ($status = 1); 
  1326.     }
  1327.     if (wantarray) {
  1328.     return ($status, @@results);
  1329.     }
  1330.     if ($status) {
  1331.     return $status;
  1332.     }
  1333.     @@status = grep("$_ != 0", @@results);
  1334.     if ($#status >= $[) {
  1335.     return $status[0];
  1336.     }
  1337.     return 0;
  1338. }
  1339.  
  1340.  
  1341. #
  1342. # VerifyCurrent($path, *stale, *modified)
  1343. #
  1344. # Check the status of the files in the current directory and its 
  1345. # subdirectories to see if they are out of date.
  1346. #
  1347. # Results: 0 if successful, 1 otherwise;
  1348. #
  1349. # Side effects: 
  1350. #
  1351. sub VerifyCurrent {
  1352.     local($path) = shift;
  1353.     local(*stale) = shift;
  1354.     local(*modified) = shift;
  1355.     local($files) = shift;
  1356.     local($pwd) = $ENV{'PWD'};
  1357.     local($status) = 0;
  1358.     local($substatus) = 0;
  1359.     local($current) = 1;
  1360.     local($mod) = 0;
  1361.     local($link, $old, $new, %links);
  1362.  
  1363.     printf("Verifying that $path is current\n") if ($debug);
  1364.     if (!-d "CVS.adm") {
  1365.     return 0;
  1366.     }
  1367.     open(CHK, "cvs -d $cvsroot info |") ||
  1368.     return &Error(1, "Can't get info for $path: $!\n");
  1369.     while(<CHK>) {
  1370.     if (/^U\s+(\S+)/) {
  1371.         printf("File $path/$1 is out of date or needs to be added.\n");
  1372.         $current = 0;
  1373.     } elsif (/^D\s+(\S+)/) {
  1374.         printf("File $path/$1 has been removed from the repository.\n");
  1375.         $current = 0;
  1376.     } elsif (/^C\s+(\S+)/) {
  1377.         printf("File $path/$1 is out of date.\n");
  1378.         $current = 0;
  1379.     } elsif (/^[MARC]/) {
  1380.         $mod = 1;
  1381.     } 
  1382.     }
  1383.     close(CHK);
  1384.     if (!$current) {
  1385.     printf("$path is not current\n") if ($debug);
  1386.     push(@@stale, $path);
  1387.     }
  1388.     if ($mod) {
  1389.     printf("$path has been modified\n") if ($debug);
  1390.     push(@@modified, $path);
  1391.     } elsif (-f "SCVS/$linkFile") {
  1392.     open(VERIFY1, "SCVS/$linkFile") ||
  1393.         return &Error(1, "Open of SCVS/$linkFile failed: $!\n");
  1394.     open(VERIFY2, ">SCVS/$tmpfile") ||
  1395.         return &Error(1, "Open of SCVS/$tmpfile failed: $!\n");
  1396.     while(<VERIFY1>) {
  1397.         next if (/^#/);
  1398.         if (/(\S+)\s+(\S+)/) {
  1399.         ($link, $old) = ($1, $2);
  1400.         if ($link !~ /^[*]/) {
  1401.             $new = readlink($link);
  1402.             if (!defined($new)) {
  1403.             return &Error(1, "Can't read link $link\n");
  1404.             }
  1405.             s/$old/$new/;
  1406.         }
  1407.         }
  1408.     }
  1409.     continue {
  1410.         print VERIFY2;
  1411.     }
  1412.     close(VERIFY1);
  1413.     close(VERIFY2);
  1414.     if (!rename("SCVS/$tmpfile", "SCVS/$linkFile")) {
  1415.         printf("Rename of SCVS/$tmpfile to SCVS/$linkFile failed:$!\n");
  1416.         unlink("SCVS/$tmpfile");
  1417.         return 1;
  1418.     }
  1419.     }
  1420.     if ($recurse) {
  1421.     $status = &AllSubdirs($path, "VerifyCurrent", *stale, *modified);
  1422.     }
  1423.     return $status;
  1424. }
  1425.  
  1426. #
  1427. # UpdateInstalled(@@files)
  1428. #
  1429. # Update the installed copy of the sources.  This is done on commit.
  1430. # If @@files is not specified then the entire directory and its subdirectories
  1431. # are updated.
  1432. #
  1433. # Results: 0 if successful, 1 otherwise
  1434. #
  1435. # Side effects: The installed sources are updated.
  1436. #
  1437. sub UpdateInstalled {
  1438.     local(@@files) = @@_;
  1439.     local($dir);
  1440.     local($pwd) = $ENV{'PWD'};
  1441.     local($module);
  1442.     local($tail);
  1443.     local(@@args) = ("-q");
  1444.  
  1445.     printf(STDERR "UpdateInstalled\n") if ($debug);
  1446.     $module = &GetModuleName();
  1447.     if (!defined($module)) {
  1448.     print("Can't file module name for dir $pwd\n");
  1449.     return 1;
  1450.     }
  1451.     $dir = &ReadFile("CVS.adm/Repository", 1);
  1452.     if (!defined($dir)) {
  1453.     return 1;
  1454.     }
  1455.     chop($dir);
  1456.     $tail = substr($dir, rindex($dir, '/') + 1);
  1457.     if ($tail eq "SCVS") {
  1458.     $dir = substr($dir, 0, rindex($dir, '/'));
  1459.     }
  1460.     if (! -d "$installdir/$dir") {
  1461.     print("No installed source $installdir/$dir\n") if ($debug);
  1462.     return 0;
  1463.     }
  1464.     &Chdir("$installdir/$dir") == 0 || return 1;
  1465.     &UpdateCmd(0, @@args, @@files) == 0 || return 1;
  1466.     &Chdir("$pwd") == 0 || return 1;
  1467.     return 0;
  1468. }
  1469.  
  1470.  
  1471.  
  1472. #
  1473. # Commit
  1474. #
  1475. # Commit the current directory and its subdirectories.
  1476. #
  1477. # Results: 0 if successful, 1 otherwise
  1478. #
  1479. # Side effects: 
  1480. #
  1481. sub Commit {
  1482.     local($path) = shift;
  1483.     local($args) = shift;
  1484.     local($files) = shift;
  1485.     local($pwd) = $ENV{'PWD'};
  1486.     local($status) = 0;
  1487.     local($output);
  1488.     local($tail);
  1489.  
  1490.  
  1491.     printf(STDERR "Commit $path $args $files\n") if ($debug);
  1492.     if (!-d "CVS.adm") {
  1493.     return 0;
  1494.     }
  1495.     printf("$path:\n");
  1496.     $tail = substr($path, rindex($path, '/') + 1);
  1497.     #
  1498.     # Before we commit the SCVS links file we remove all the deleted links
  1499.     # from it.
  1500.     #
  1501.     if ($tail eq "SCVS") {
  1502.     if (open(CMTDIR1, "$linkFile")) {
  1503.         open(CMTDIR2, ">$tmpfile") ||
  1504.         return &Error(1, "Open of $path/$tmpfile failed: $!\n");
  1505.         while(<CMTDIR1>) {
  1506.         next if (/^[*]/);
  1507.         print CMTDIR2 $_;
  1508.         }
  1509.         close(CMTDIR1);
  1510.         close(CMTDIR2);
  1511.         if (!rename("$tmpfile", "$linkFile")) {
  1512.         printf("Rename of $tmpfile to $linkFile failed:$!\n");
  1513.         unlink("$tmpfile");
  1514.         return 1;
  1515.         }
  1516.         &System("cvs -d $cvsroot $cvsCmdArgs $readonly ci -f -m scvs -a");
  1517.         return $status;
  1518.     }
  1519.     }
  1520.     if ($files ne "") {
  1521.     &System("cvs -d $cvsroot $cvsCmdArgs $readonly ci -f $args $files");
  1522.     } else {
  1523.     &System("cvs -d $cvsroot $cvsCmdArgs $readonly ci -f -a $args");
  1524.     }
  1525.     return $status;
  1526. }
  1527.  
  1528. #
  1529. # CommitCmd(@@names)
  1530. #
  1531. # Commit any changes to the modules or files. 
  1532. # Otherwise all changed files in the current directory and any subdirectories
  1533. # are committed.  Before anything is committed it is checked that all
  1534. # files are up-to-date.  If they aren't, a message is printed and the
  1535. # commit is not done.
  1536. #
  1537. # Results: 0 if successful, 1 otherwise
  1538. #
  1539. # Side effects: 
  1540. #
  1541.  
  1542. sub CommitCmd {
  1543.     local(@@names) = @@_;
  1544.     local(%dirs);
  1545.     local($i);
  1546.     local($status) = 0;
  1547.     local($path);
  1548.     local(@@stale, @@modified);
  1549.     local($tmp);
  1550.     local($args);
  1551.     local($quiet) = 0;
  1552.     local($owd) = $ENV{'PWD'};
  1553.     local(@@options) = (
  1554.     "l", $OPT_FALSE, *recurse, "Don't recurse on subdirs",
  1555.     "f", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1556.     "n", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1557.     "m", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  1558.     "r", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  1559.     "q", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1560.     "Q", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  1561.     );
  1562.  
  1563.     $recurse = 1;
  1564.     undef($cvsargs);
  1565.     &Opt_Parse(*names, @@options, $optFlags);
  1566.     $args = $cvsargs;
  1567.     if (@@errors = grep(/^-/, @@names)) {
  1568.     print("Unknown options \"@@errors\" to commit command\n");
  1569.     return 1;
  1570.     }
  1571.     if ($args =~ /-q|-Q/) {
  1572.     $quiet = 1;
  1573.     } else {
  1574.     $args .= " -q";
  1575.     }
  1576.     if (! $quiet) {
  1577.     print("Verifying that sources are up-to-date.\n");
  1578.     }
  1579.     %dirs = &ProcessNames(1, @@names);
  1580.     if ($recurse && $dirs{"."} eq "") {
  1581.     $doall = 1;
  1582.     }
  1583.     if ($debug) {
  1584.     print("CommitCmd\n");
  1585.     while (($i, $files) = each %dirs) {
  1586.         print("$i = $files\n");
  1587.     }
  1588.     }
  1589.     $status = &Lock("w", keys(%dirs)); 
  1590.     if ($status) {
  1591.     return $status;
  1592.     }
  1593. module:
  1594.     while (($i, $files) = each(%dirs)) {
  1595.     &Chdir($i) == 0 || return 1; 
  1596.     $status = &VerifyCurrent($i, *stale, *modified);
  1597.     if ($status) {
  1598.         return $status;
  1599.     }
  1600.     &Chdir($owd) == 0 || return 1; 
  1601.     }
  1602.  
  1603.     if ($#stale >= $[) {
  1604.     printf("Update your sources using \"scvs update\".\n");
  1605.     return $status;
  1606.     }
  1607.  
  1608.     if (! $quiet) {
  1609.     print("Committing sources in modified directories.\n");
  1610.     }
  1611.     #
  1612.     # Commit all directories that were modified.
  1613.     #
  1614.     foreach $i (@@modified) {
  1615.     if (!$doall && $dir{$i} eq "" && $i ne ".") {
  1616.         next;
  1617.     }
  1618.     print("$i = $files\n") if ($debug);
  1619.     &Chdir($i) == 0 || return 1; 
  1620.     $status = &Commit($i, $args, $dirs{$i});
  1621.     &Chdir($owd) == 0 || return 1; 
  1622.     }
  1623.     if (defined($installdir)) {
  1624.     # 
  1625.     # Update the installed copy of the sources.
  1626.     #
  1627.     if (! $quiet) {
  1628.         print("Updating installed copies.\n");
  1629.     }
  1630.     foreach $i (@@modified) {
  1631.         &Chdir($i) == 0 || return 1; 
  1632.         $status = &UpdateInstalled();
  1633.         &Chdir($owd) == 0 || return 1; 
  1634.     }
  1635.     }
  1636.     return $status;
  1637. }
  1638.  
  1639.  
  1640. #
  1641. # WhoCmd(@@modules)
  1642. #
  1643. # Print the names of users who have the modules checked out.
  1644. #
  1645. # Results: 0 if successful, 1 otherwise
  1646. #
  1647. # Side effects: 
  1648. #
  1649.  
  1650. sub WhoCmd {
  1651.     local(@@modules) = @@_;
  1652.     local($pwd, $i);
  1653.     local($status) = 0;
  1654.     local($cvsdir, @@who, $user, %users, $line);
  1655.  
  1656.     if ($#modules < $[) {
  1657.     @@modules = (".");
  1658.     }
  1659.     $status = &Lock("r",@@modules); 
  1660.     if ($status) {
  1661.     return $status;
  1662.     }
  1663.     $pwd = $ENV{'PWD'};
  1664.  
  1665. module:
  1666.     foreach $i (@@modules) {
  1667.     if (!$quiet) {
  1668.         print("$i\n");
  1669.     }
  1670.     if ($i eq ".") {
  1671.         $i = &GetModuleName();
  1672.         if (!defined($i)) {
  1673.         $status = 1;
  1674.         next module;
  1675.         }
  1676.     }
  1677.     if (!defined($moduleToRepos{$i})) {
  1678.         printf(STDERR "$i module does not exist.\n");
  1679.         $status = 1;
  1680.         next module;
  1681.     }
  1682.     $cvsdir = $cvsroot . "/" . $moduleToRepos{$i};
  1683.     @@who = &ReadFile("$cvsdir/$userFile", 1);
  1684.     foreach $line (@@who) {
  1685.         ($user) = split(' ', $line);
  1686.         $users{$user} = 1;
  1687.     }
  1688.     foreach $user (keys %users) {
  1689.         printf("$user\n");
  1690.     }
  1691.     }
  1692.     return $status;
  1693. }
  1694.  
  1695. #
  1696. # AddCmd(@@names)
  1697. #
  1698. # Add a file, directory, or symbolic link to a directory.
  1699. #
  1700. # Results: 0 if successful, 1 otherwise
  1701. #
  1702. # Side effects: 
  1703. #
  1704.  
  1705. sub AddCmd {
  1706.     local(@@names) = @@_;
  1707.     local($i);
  1708.     local($status) = 0;
  1709.     local(%links);
  1710.     local($pwd) = $ENV{'PWD'};
  1711.     local($module);
  1712.     local($args);
  1713.     local(@@options) = (
  1714.     "m", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  1715.     );
  1716.  
  1717.     undef($cvsargs);
  1718.     &Opt_Parse(*names, @@options, $optFlags);
  1719.     $args = $cvsargs;
  1720.     if (@@errors = grep(/^-/, @@names)) {
  1721.     print("Unknown options \"@@errors\" to add command\n");
  1722.     return 1;
  1723.     }
  1724.  
  1725.     if ($#names < $[) {
  1726.     return &Error(1, "Add command requires list of files\n");
  1727.     }
  1728.     $module = &GetModuleName();
  1729.     if (!defined($module)) {
  1730.     return 1;
  1731.     }
  1732. name:
  1733.     foreach $i (@@names) {
  1734.     if (-l $i) {
  1735.         local($target) = readlink($i);
  1736.         if (!defined($target)) {
  1737.         printf("$i does not exist\n");
  1738.         $status = 1;
  1739.         next name;
  1740.         }
  1741.         if (open(ADD, "SCVS/$linkFile")) {
  1742.         while(<ADD>) {
  1743.             if (/^$i\s+(\S+)/) {
  1744.             if ($target ne $1) {
  1745.                 printf("Link $i already points to $1.\n");
  1746.             } else {
  1747.                 printf("Link $i already added.\n");
  1748.             }
  1749.             $status = 1;
  1750.             close(ADD);
  1751.             next name;
  1752.             }
  1753.         }
  1754.         close(ADD);
  1755.         } elsif (! -f "SCVS/$linkFile") {
  1756.         open(ADD, ">SCVS/$linkFile") ||
  1757.             return &Error(1, "Can't open SCVS/$linkFile: $!\n");
  1758.         printf(ADD 
  1759.         "# This file is used by scvs and contains symbolic link\n");
  1760.         printf(ADD 
  1761.         "# information.  Each line is of the form \"link target\"\n");
  1762.         printf(ADD "# \$Header\n");
  1763.         close(ADD);
  1764.         &Chdir("SCVS") == 0 || return 1; 
  1765.         printf("Adding $linkFile directory\n") if ($debug);
  1766.         &System(
  1767.             "cvs -d $cvsroot $readonly add -m \"sym links\" $linkFile");
  1768.         &Chdir($pwd) == 0 || return 1; 
  1769.         } else {
  1770.         return &Error(1, "Open of SCVS/$linkFile failed: $!\n");
  1771.         }
  1772.         $links{$i} = $target;
  1773.     } else {
  1774.         &System("cvs -d $cvsroot $cvsCmdArgs $readonly add $args $i");
  1775.         if (-d $i) {
  1776.         # 
  1777.         # If we are adding a directory then we should create an
  1778.         # SCVS subdirectory in it.
  1779.         #
  1780.         if (! -d "$i/SCVS") {
  1781.             mkdir("$i/SCVS", 0770) ||
  1782.             return &Error(1, "Mkdir of $i/SCVS failed: $!\n");
  1783.             &Chdir("$i/SCVS") == 0 || return 1; 
  1784.             open(ADD, ">module") ||
  1785.             return &Error(1, "Open of $i/SCVS/module failed: $!\n");
  1786.             printf(ADD "$module\n");
  1787.             close(ADD);
  1788.             &System("cvs -d $cvsroot $readonly add module");
  1789.             &Chdir($pwd) == 0 || return 1; 
  1790.         }
  1791.         }
  1792.     }
  1793.     if (defined(%links)) {
  1794.         open(ADD, ">>SCVS/$linkFile") ||
  1795.         return &Error(1, "Open of SCVS/$linkFile failed: $!\n");
  1796.         while (($i, $target) = each(%links)) {
  1797.         printf("Adding link $i -> $target\n") if ($debug);
  1798.         printf(ADD "%-24s %s\n", $i, $target);
  1799.         }
  1800.         close(ADD);
  1801.     }
  1802.     }
  1803.     return $status;
  1804. }
  1805. #
  1806. # RemoveCmd(@@names)
  1807. #
  1808. # Removes a file, directory, or symbolic link from a directory.
  1809. #
  1810. # Results: 0 if successful, 1 otherwise
  1811. #
  1812. # Side effects: 
  1813. #
  1814.  
  1815. sub RemoveCmd {
  1816.     local(@@names) = @@_;
  1817.     local($i);
  1818.     local($status, %links, @@delete) = 0;
  1819.  
  1820.     if ($#names < $[) {
  1821.     return &Error(1, "Remove command requires list of files\n");
  1822.     }
  1823.     if (open(RM, "SCVS/$linkFile")) {
  1824.     while(<RM>) {
  1825.         next if (/^#/);
  1826.         if (/^([^*]\S+)\s+(\S+)/) {
  1827.         printf("Found link $1 -> $2\n") if ($debug);
  1828.         $links{$1} = $2;
  1829.         }
  1830.     }
  1831.     close(RM);
  1832.     }
  1833. name:
  1834.     foreach $i (@@names) {
  1835.     if ((-e $i) || (-l $i)) {
  1836.         if (-d $i) {
  1837.         print("Ignoring remove of directory $i\n");
  1838.         next name;
  1839.         }
  1840.         printf("Deleting existing $i\n");
  1841.         if (!unlink("$i")) {
  1842.         printf("Unlink failed: $!\n");
  1843.         $status = 1;
  1844.         next name;
  1845.         }
  1846.     }
  1847.     if (defined($links{$i})) {
  1848.         printf("Putting $i on delete list\n") if ($debug);
  1849.         push(@@delete, $i);
  1850.     } else {
  1851.         &System("cvs -d $cvsroot $cvsCmdArgs $readonly remove $i");
  1852.     }
  1853.     }
  1854.     if ($#delete >= $[) {
  1855.     if (!open(RM1, "SCVS/$linkFile")) {
  1856.         printf("Can't open SCVS/$linkFile: $!\n");
  1857.         $status = 1;
  1858.         next name;
  1859.     }
  1860.     if (!open(RM2, ">$tmpfile")) {
  1861.         printf("Can't open $tmpfile: $!\n");
  1862.         $status = 1;
  1863.         next name;
  1864.     }
  1865. line:
  1866.     while (<RM1>) {
  1867.         if (/^([^#*]\S+)\s+(\S+)/) {
  1868.         for ($i = 0; $i <= $#delete; $i++) {
  1869.             if ($delete[$i] eq $1) {
  1870.             splice(@@delete, $i, 1);
  1871.             print RM2 "*$_";
  1872.             next line;
  1873.             }
  1874.         }
  1875.         }
  1876.         print RM2 $_;
  1877.     }
  1878.     close(RM1);
  1879.     close(RM2);
  1880.     if (!rename("$tmpfile", "SCVS/$linkFile")) {
  1881.         printf("Rename of $tmpfile to SCVS/$linkFile failed:$!\n");
  1882.         unlink("$tmpfile");
  1883.         $status = 1;
  1884.     }
  1885.     }
  1886.     return $status;
  1887. }
  1888. #
  1889. # Info($path)
  1890. #
  1891. # Prints out status information for the current directory and recurses
  1892. # on subdirectories.
  1893. #
  1894. # Results: 0 if successful, 1 otherwise
  1895. #
  1896. # Side effects: 
  1897. #
  1898. sub Info {
  1899.     local($path) = shift;
  1900.     local($files) = shift;
  1901.     local($tail);
  1902.     local($diff) = 0;
  1903.     local($cat) = 0;
  1904.     local($i);
  1905.     local($pwd) = $ENV{'PWD'};
  1906.  
  1907.     if (!-d "CVS.adm") {
  1908.     return 0;
  1909.     }
  1910.     $tail = substr($path, rindex($path, '/') + 1);
  1911.     if ($tail eq "SCVS") {
  1912.     return 0;
  1913.     }
  1914.     if (! $quiet) {
  1915.     print("$path\n");
  1916.     }
  1917.     &System("cvs -d $cvsroot $cvsCmdArgs $readonly info $files");
  1918.     if ($files eq "") {
  1919.     if (-d "SCVS") {
  1920.         &Chdir("SCVS") == 0 || return 1;
  1921.         open(INFO, "cvs -d $cvsroot $readonly info |") ||
  1922.         return &Error(1, "Can't do cvs info on $path: $!\n");
  1923.         while(<INFO>) {
  1924.         if (/^[UMC]\s+$linkFile/) {
  1925.             $diff = 1;
  1926.             last;
  1927.         } elsif (/^[AD]\s+$linkFile/) {
  1928.             $cat = 1;
  1929.             last;
  1930.         }
  1931.         }
  1932.         close(INFO);
  1933.         if ($diff) {
  1934.         local(%updated);
  1935.         open(INFO, "cvs -d $cvsroot $readonly diff $linkFile |") ||
  1936.             return &Error(1, 
  1937.             "Can't do cvs diff on $path/$linkFile: $!\n");
  1938.         while(<INFO>) {
  1939.             if (/^>\s+([^*]\S+)/) {
  1940.             printf("A %s\@@\n", $1);
  1941.             } elsif (/^>\s+[*](\S+)/) {
  1942.             printf("R %s\@@\n", $1);
  1943.             delete $updated{$1};
  1944.             } elsif (/^<\s+([^*]\S+)/) {
  1945.             $updated{$1} = 1;
  1946.             } elsif (/^<\s+[*](\S+)/) {
  1947.             printf("D %s\@@\n", $1);
  1948.             }
  1949.         }
  1950.         close(INFO);
  1951.         foreach $i (keys %updated) {
  1952.             printf("U %s\@@\n", $i);
  1953.         }
  1954.         }
  1955.         if ($cat) {
  1956.         open(INFO, "$linkFile") ||
  1957.             return &Error(1, "Open of $linkFile failed: $!\n");
  1958.         while(<INFO>) {
  1959.             next if (/^#/);
  1960.             if (/^([^*]\S+)/) {
  1961.             printf("A %s\@@\n", $1);
  1962.             } elsif (/^([*]\S+)/) {
  1963.             printf("R %s\@@\n", $1);
  1964.             }
  1965.         }
  1966.         close(INFO);
  1967.         }
  1968.         &Chdir($pwd) == 0 || return 1;
  1969.     }
  1970.     if (($recurse) && ($files eq "")) {
  1971.         $status = &AllSubdirs($path, "Info");
  1972.     }
  1973.     }
  1974. }
  1975.  
  1976. #
  1977. # InfoCmd(@@modules)
  1978. #
  1979. # Prints out status information for the given modules.
  1980. #
  1981. # Results: 0 if successful, 1 otherwise
  1982. #
  1983. # Side effects: 
  1984. #
  1985.  
  1986. sub InfoCmd {
  1987.     local(@@names) = @@_;
  1988.     local(%dirs);
  1989.     local($pwd, $i);
  1990.     local($status) = 0;
  1991.     local(@@options) = ("l", $OPT_FALSE, *recurse, "Don't recurse on subdirs");
  1992.     local($buffer);
  1993.  
  1994.     $recurse = 1;
  1995.     undef($cvsargs);
  1996.     &Opt_Parse(*modules, @@options, $optFlags);
  1997.  
  1998.     %dirs = &ProcessNames(1, @@names);
  1999.  
  2000.     #
  2001.     # Lock the modules.
  2002.     #
  2003.     if ($lock) {
  2004.     $status = &Lock("r", keys(%dirs)); 
  2005.     if ($status) {
  2006.         return $status;
  2007.     }
  2008.     }
  2009.     $owd = $ENV{'PWD'};
  2010. dir: 
  2011.     while (($i, $files) = each(%dirs)) {
  2012.     &Chdir($i) == 0 || return 1;
  2013.     &GetCheckoutArgs();
  2014.     $status = &Info($i, $files);
  2015.     if ($status) {
  2016.         return $status;
  2017.     }
  2018.     &Chdir($owd) == 0 || return 1; 
  2019.     }
  2020.     return $status;
  2021. }
  2022.  
  2023. #
  2024. # DiffFile($path, $file, $args, $current)
  2025. #
  2026. # Prints out status information for the current directory and recurses
  2027. # on subdirectories.
  2028. #
  2029. # Results: 0 if successful, 1 otherwise
  2030. #
  2031. # Side effects: 
  2032. #
  2033. sub DiffFile {
  2034.     local($path) = shift;    # Current path.
  2035.     local($file) = shift;    # File to diff.
  2036.     local($args) = shift;    # args to cvs diff.
  2037.     local($current) = shift;    # Should we diff with current version.
  2038.     local($tail);
  2039.     local($pwd) = $ENV{'PWD'};
  2040.     local($status) = 0;
  2041.     local($version) = "";
  2042.     local($repository);
  2043.  
  2044.     if (!-d "CVS.adm") {
  2045.     return 0;
  2046.     }
  2047.     $repository = &Repository(".");
  2048.     if (!defined($repository)) {
  2049.     print("Repository not found\n") if ($debug);
  2050.     return 0;
  2051.     }
  2052.     printf("Repository is $repository\n") if ($debug);
  2053.     if (!-e "$repository/$file,v") {
  2054.     return 0;
  2055.     }
  2056.     if ($current) {
  2057.     open(DIFF, "cvs -d $cvsroot $readonly status $file |") ||
  2058.         return &Error(1, "Can't get status for $path/$file: $!\n");
  2059.     while(<DIFF>) {
  2060.         if (/^RCS:\s+(\S+)/) {
  2061.         $version = "-r $1";
  2062.         last;
  2063.         }
  2064.     }
  2065.     close(DIFF);
  2066.     }
  2067.     &System("cvs -d $cvsroot $cvsCmdArgs $readonly diff $version $args $file");
  2068. }
  2069.  
  2070. #
  2071. # Diff($path, $args, $current)
  2072. #
  2073. # Prints out status information for the current directory and recurses
  2074. # on subdirectories.
  2075. #
  2076. # Results: 0 if successful, 1 otherwise
  2077. #
  2078. # Side effects: 
  2079. #
  2080. sub Diff {
  2081.     local($path) = shift;    # Current path.
  2082.     local($args) = shift;    # args to cvs diff.
  2083.     local($current) = shift;    # Should we diff with current version.
  2084.     local($tail);
  2085.     local($pwd) = $ENV{'PWD'};
  2086.     local($file);
  2087.     local($status) = 0;
  2088.  
  2089.     if (!-d "CVS.adm") {
  2090.     return 0;
  2091.     }
  2092.     $tail = substr($path, rindex($path, '/') + 1);
  2093.     if ($tail eq "SCVS") {
  2094.     return 0;
  2095.     }
  2096.     opendir(THISDIR, ".") || return &Error(1, "Opendir of $path failed: $!\n");
  2097.     foreach $file (grep(-f, readdir(THISDIR))) {
  2098.     printf(STDERR "$file\n") if ($debug);
  2099.     $status = &DiffFile($path, $file, $args, $current);
  2100.     if ($status) {
  2101.         return $status;
  2102.     }
  2103.     }
  2104.     if ($recurse) {
  2105.     $status = &AllSubdirs($path, "Diff", $args, $current);
  2106.     }
  2107. }
  2108.  
  2109.  
  2110.  
  2111. #
  2112. # DiffCmd(@@modules)
  2113. #
  2114. # Does an rcsdiff on the modules or directories
  2115. #
  2116. # Results: 0 if successful, 1 otherwise
  2117. #
  2118. # Side effects: 
  2119. #
  2120.  
  2121. sub DiffCmd {
  2122.     local(@@modules) = @@_;
  2123.     local($pwd, $i);
  2124.     local($status) = 0;
  2125.     local($current) = 0;
  2126.     local(@@options) = (
  2127.     "R", $OPT_TRUE, *current, "Diff with current version",
  2128.     "l", $OPT_FALSE, *recurse, "Recurse on subdirectories",
  2129.     "b", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2130.     "i", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2131.     "w", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2132.     "t", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2133.     "c", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2134.     "e", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2135.     "f", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2136.     "h", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2137.     "n", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2138.     "r", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  2139.     "q", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2140.     "Q", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2141.     );
  2142.  
  2143.     $recurse = 1;
  2144.     undef($cvsargs);
  2145.     &Opt_Parse(*modules, @@options, $optFlags);
  2146.     if (@@errors = grep(/^-/, @@modules)) {
  2147.     print("Unknown options \"@@errors\" to diff command\n");
  2148.     return 1;
  2149.     }
  2150.     print "@@modules\n" if ($debug);
  2151.     if ($#modules < $[) {
  2152.     push(@@modules, ".");
  2153.     }
  2154.     if (! -d $modules[0]) {
  2155.     $status = &Lock("r","."); 
  2156.     if ($status) {
  2157.         return $status;
  2158.     }
  2159.     foreach $i (@@modules) {
  2160.         &DiffFile(".", $i, $cvsargs, $current);
  2161.     }
  2162.     } else {
  2163.     $status = &Lock("r",@@modules);
  2164.     if ($status) {
  2165.         return $status;
  2166.     }
  2167.     $pwd = $ENV{'PWD'};
  2168.  
  2169.     foreach $i (@@modules) {
  2170.         printf("DiffCmd $i\n") if ($debug);
  2171.         &Chdir($i) == 0 || return 1; 
  2172.         &GetCheckoutArgs();
  2173.         $status = &Diff($i, $cvsargs, $current);
  2174.         if ($status) {
  2175.         return $status;
  2176.         }
  2177.         &Chdir($pwd) == 0 || return 1; 
  2178.     }
  2179.     }
  2180.     return $status;
  2181. }
  2182.  
  2183. #
  2184. # Cvs($path, $command)
  2185. #
  2186. # Run a cvs command in the current directory and its subdirectories.
  2187. # Any output from the command is printed.  The command is not executed
  2188. # in any "SCVS" subdirectories.
  2189. #
  2190. # Results: 0 if successful, 1 otherwise
  2191. #
  2192. # Side effects: 
  2193. #
  2194. sub Cvs {
  2195.     local($path) = shift;
  2196.     local($command) = shift;
  2197.     local($pwd) = $ENV{'PWD'};
  2198.     local($status) = 0;
  2199.     local($output, $tail);
  2200.  
  2201.     if (!-d "CVS.adm") {
  2202.     return 0;
  2203.     }
  2204.     $tail = substr($path, rindex($path, '/') + 1);
  2205.     if ($tail eq "SCVS") {
  2206.     return 0;
  2207.     }
  2208.     printf("%s\n", $path);
  2209.     &System("cvs -d $cvsroot $cvsCmdArgs $readonly $command");
  2210.     if ($recurse) {
  2211.     $status = &AllSubdirs($path, "Cvs", $command);
  2212.     }
  2213.     return $status;
  2214. }
  2215.  
  2216.  
  2217. #
  2218. # CvsCmd($command, @@modules)
  2219. #
  2220. # Runs a cvs command on each module and its subdirectories.
  2221. # Any output from the command is printed.
  2222. #
  2223. # Results: 0 if successful, 1 otherwise
  2224. #
  2225. # Side effects: 
  2226. #
  2227.  
  2228. sub CvsCmd {
  2229.     local($command) = shift;
  2230.     local(@@modules) = @@_;
  2231.     local($i, @@args);
  2232.     local($status) = 0;
  2233.     local($path);
  2234.     local($pwd) = $ENV{'PWD'};
  2235.     local(@@options) = (
  2236.     "l", $OPT_FALSE, *recurse, "Don't recurse on subdirs",
  2237.     "L", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2238.     "R", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2239.     "h", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2240.     "t", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2241.     "b", $OPT_FUNC, "CvsOpt1", $OPT_NULL,
  2242.     "d", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  2243.     "l", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  2244.     "r", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  2245.     "s", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  2246.     "w", $OPT_FUNC, "CvsOpt2", $OPT_NULL,
  2247.     );
  2248.  
  2249.  
  2250.     $recurse = 1;
  2251.     undef($cvsargs);
  2252.     &Opt_Parse(*modules, @@options, $optFlags);
  2253.     if (@@errors = grep(/^-/, @@modules)) {
  2254.     print("Unknown options \"@@errors\" to $command command\n");
  2255.     return 1;
  2256.     }
  2257.  
  2258.     if ($#modules < $[) {
  2259.     push(@@modules, ".");
  2260.     }
  2261.     if (! -d $modules[0]) {
  2262.     $status = &Lock("r","."); 
  2263.     if ($status) {
  2264.         return $status;
  2265.     }
  2266.     $tmp = 
  2267.         "cvs -d $cvsroot $cvsCmdArgs $readonly $command $cvsargs @@modules";
  2268.     &System($tmp);
  2269.     } else {
  2270.     $status = &Lock("r", @@modules); 
  2271.     if ($status) {
  2272.         return $status;
  2273.     }
  2274. module: 
  2275.     foreach $i (@@modules) {
  2276.         &Chdir($i) == 0 || return 1; 
  2277.         &GetCheckoutArgs();
  2278.         $status = &Cvs($i, $command);
  2279.         &Chdir($pwd) == 0 || return 1; 
  2280.     }
  2281.     }
  2282.     return $status;
  2283. }
  2284.  
  2285.  
  2286.  
  2287. #
  2288. # Exit
  2289. #
  2290. # Exit with a status of 1.
  2291. #
  2292. # Results: Doesn't return
  2293. #
  2294. # Side effects: The script exits.
  2295. #
  2296.  
  2297.  
  2298. sub Exit {
  2299.     exit(1);
  2300. }
  2301.  
  2302.  
  2303. #
  2304. # Usage(@@optionArray)
  2305. #
  2306. # Print out help information.
  2307. #
  2308. # Results: None
  2309. #
  2310. # Side effects: Stuff is printed
  2311. #
  2312. sub Usage {
  2313.     local(@@options) = @@_;
  2314.     local(%info) = (("unpack", "Create symbolic links"),
  2315.             ("checkout", "Checkout a copy of a module"),
  2316.             ("unlock", "Unlock a module"),
  2317.             ("lock", "Lock a module"),
  2318.             ("update", "Update a copy of a module"),
  2319.             ("done", "User is done with a module"),
  2320.             ("commit", "Commit changes to a module"),
  2321.             ("who", "Print a list of users with copies of a module"),
  2322.             ("diff", "Do rcsdiff on files you have changed"),
  2323.             ("status", "Print out rcs status of files"),
  2324.             ("log", "Print rcs log of files"),
  2325.             ("join", "Merge in new vendor release"),
  2326.             ("patch", "Create a patch file"),
  2327.             ("tag", "Tag a version"));
  2328.  
  2329.     &Opt_PrintUsage(@@options);
  2330.     printf("\nValid commands are:\n");
  2331.     foreach $i sort ("unpack", "checkout", "unlock", "lock", "update", 
  2332.             "done", "commit", "who", "diff", "status", "log",
  2333.             @@cvsCmds) {
  2334.     printf("\t$i\t%s\n", $info{$i});
  2335.     }
  2336. }
  2337.  
  2338. #
  2339. # Error($status, @@args)
  2340. #
  2341. # Prints @@args to STDERR, and returns $status
  2342. #
  2343. # Results: $status
  2344. #
  2345. # Side effects: Stuff is printed
  2346. #
  2347. sub Error {
  2348.     local($status) = shift;
  2349.     if ($#_ >= $[) {
  2350.     printf(STDERR @@_);
  2351.     }
  2352.     return $status;
  2353. }
  2354.  
  2355. #
  2356. # ReadFile($file, $ignoreComments)
  2357. #
  2358. # Reads the contents of the given file.  If $ignoreComments is non-zero
  2359. # then any line beginning with '#' is ignored.  
  2360. #
  2361. # Results: An array containing each line of the file.  If a scalar is
  2362. #     wanted then only the first line is returned.
  2363. #
  2364. # Side effects: 
  2365. #
  2366. sub ReadFile {
  2367.     local($file) = shift;
  2368.     local($ignoreComments) = shift; 
  2369.     local(@@contents);
  2370.     open(READ, "$file") ||
  2371.     return &Error(undef, "Open of $file in $ENV{'PWD'} failed: $!\n");
  2372.     if ($ignoreComments) {
  2373.     @@contents = grep(!/^#/, <READ>);
  2374.     } else {
  2375.     @@contents = <READ>;
  2376.     }
  2377.     close(READ);
  2378.     if ($#contents < $[) {
  2379.     return undef;
  2380.     }
  2381.     if (wantarray) {
  2382.     return @@contents;
  2383.     } 
  2384.     return($contents[0]);
  2385. }
  2386.  
  2387. #
  2388. # WriteFile($file, @@args)
  2389. #
  2390. # Writes @@args to $file.  The file is created if it doesn't exist.
  2391. #
  2392. # Results: 0 if successful, 1 otherwise
  2393. #
  2394. # Side effects:  $file may be created, and it is written.
  2395. #
  2396. sub WriteFile {
  2397.     local($file) = shift;
  2398.     open(WRITE, ">$file") ||
  2399.     return &Error(1, "Open of $file failed: $!\n");
  2400.     print WRITE @@_;
  2401.     close(WRITE);
  2402.     return 0;
  2403. }
  2404.  
  2405.  
  2406. #
  2407. # GetModuleName
  2408. #
  2409. # Gets the module name associated with a directory.
  2410. # If no directory is specified then the current working directory is used.
  2411. #
  2412. # Results: The module name.
  2413. #
  2414. # Side effects:  The cwdToModule array is filled in.
  2415. #
  2416. sub GetModuleName {
  2417.     local($dir) = shift;
  2418.     local($reposDir);
  2419.     local($index);
  2420.     local(@@path);
  2421.     local($result) = undef; 
  2422.     local($found) = 0;
  2423.     local($i);
  2424.     local($owd) = $ENV{'PWD'};
  2425.     local($cwd);
  2426.     local($name);
  2427.  
  2428.  
  2429.     if (defined($dir)) {
  2430.     &Chdir($dir) == 0 || return undef;
  2431.     }
  2432.     print("GetModuleName: $dir\n") if ($debug);
  2433.     $cwd = $ENV{'PWD'};
  2434.     print("cwd = $cwd\n") if ($debug);
  2435.     $name = $cwdToModule{$cwd};
  2436.     if (!defined($result)) {
  2437.     if (! -f "CVS.adm/Repository") {
  2438.         return undef;
  2439.     }
  2440.     $reposDir = &ReadFile("CVS.adm/Repository", 1);
  2441.     chop($reposDir);
  2442.     printf("$reposDir\n") if ($debug);
  2443.     if (defined($reposDir)) {
  2444.         while($reposDir ne "") {
  2445.         $name = $reposToModule{$reposDir};
  2446.         if (defined($name)) {
  2447.             printf("Module $name\n") if ($debug);
  2448.             $result = $name;
  2449.             last;
  2450.         }
  2451.         $index = rindex($reposDir, '/');
  2452.         last if ($index < $[);
  2453.         $reposDir = substr($reposDir, 0, $index);
  2454.         }
  2455.     }
  2456.     }
  2457.     if (defined($result)) {
  2458.     $cwdToModule{$cwd} = $name;
  2459.     }
  2460.     if (defined($dir)) {
  2461.     &Chdir($owd) == 0 || return undef;
  2462.     }
  2463.     return $result;
  2464. }
  2465.  
  2466. #
  2467. # GetCheckoutArgs
  2468. #
  2469. # Returns any arguments specified during the "co" command for the current
  2470. # module.
  2471. #
  2472. # Results: An array of arguments. Element 0 are the scvs arguments,
  2473. #         element 1 are the arguments to "co" itself.
  2474. #
  2475. # Side effects:  The $readonly variable is set to "-r" if -r was passed to scvs.
  2476. #        The $prune variable is set if -p was passed to "co".
  2477. #
  2478. sub GetCheckoutArgs {
  2479.     local(@@args) = ();
  2480.  
  2481.     if (-e "SCVS/root/SCVS/$argFile") {
  2482.     @@args = &ReadFile("SCVS/root/SCVS/$argFile", 1);
  2483.     chop(@@args);
  2484.     if (index($args[0], "-r") >= $[) {
  2485.         $readonly = "-r";
  2486.     }
  2487.     if (index($args[1], "-p") >= $[) {
  2488.         $prune = 1;
  2489.     }
  2490.     }
  2491.     return @@args;
  2492. }
  2493. #
  2494. # ProcessNames($complain, @@names)
  2495. #
  2496. # Processes a list of names given to a command.  The result is an 
  2497. # associated array whose keys are directory names and whose values
  2498. # are files.  If a name isn't a directory or a file is it put in
  2499. # the directory "*" if the $complain flag is 0, otherwise we
  2500. #complain.
  2501. #
  2502. # Results: An associative array.
  2503. #
  2504. # Side effects:  
  2505. #
  2506. sub  ProcessNames {
  2507.     local($complain) = shift;
  2508.     local(@@names) = @@_;
  2509.     local(%dirs, $i, $index, $tail, $files);
  2510.  
  2511.     if ($#names < $[) {
  2512.     $dirs{"."} = "";
  2513.     } else {
  2514.     foreach $i (@@names) {
  2515.         if (! -d $i) {
  2516.         if (-f $i) {
  2517.             $index = rindex($i, '/');
  2518.             if ($index >= $[) {
  2519.             $tail = substr($i, $index + 1);
  2520.             $dirs{substr($i, 0, $index)} .= "$tail "; 
  2521.             } else {
  2522.             $dirs{"."} .= "$i ";
  2523.             }
  2524.         } elsif ($complain) {
  2525.             printf("File or directory $i not found\n");
  2526.         } else {
  2527.             $dirs{'*'} .= "$i ";
  2528.         }
  2529.         } else {
  2530.         $dirs{$i} = "";
  2531.         }
  2532.     }
  2533.     }
  2534.     if ($debug) {
  2535.     print("ProcessNames\n");
  2536.     while (($i, $files) = each %dirs) {
  2537.         print("$i = $files\n");
  2538.     }
  2539.     }
  2540.     return %dirs;
  2541.  
  2542. }
  2543.  
  2544. #
  2545. # Chdir($dir)
  2546. #
  2547. # Changes the current working directory to $dir.  If the command fails
  2548. # an error message is printed. 
  2549. #
  2550. # Results: 0 if successful, 1 otherwise
  2551. #
  2552. # Side effects:  The current working directory is changed, and $ENV{'PWD'}
  2553. #     set to the new working directory.
  2554. #
  2555. sub Chdir {
  2556.     local($package, $file, $line);
  2557.     if (!defined($_[0])) {
  2558.     ($package, $file, $line) = caller;
  2559.     print("Null argument to Chdir, $file:$line\n");
  2560.     return 1;
  2561.     }
  2562.     if (!&chdir($_[0])) {
  2563.     ($package, $file, $line) = caller;
  2564.     return &Error(1, "Chdir to %s\nfrom %s failed: $!\nFile %s Line %s\n", 
  2565.         $_[0], $ENV{'PWD'}, $file,$line);
  2566.     }
  2567.     return 0;
  2568. }
  2569.  
  2570. #
  2571. # System($command)
  2572. #
  2573. # Does a system command on the buffer.
  2574. #
  2575. # Results: None
  2576. #
  2577. # Side effects:  Executes the command. 
  2578. #
  2579. sub System {
  2580.     print("System: $_[0]\n") if ($debug);
  2581.     system("$_[0]");
  2582. }
  2583.  
  2584. #
  2585. # ModMap
  2586. #
  2587. # Creates a mapping of module name to its subdirectory in the repository,
  2588. # and a mapping from the subdirectory to the module name.
  2589. #
  2590. # Results: 0 if successful, 1 otherwise
  2591. #
  2592. # Side effects:  The %moduleToRepos and %reposToModule are filled in.
  2593. #
  2594.  
  2595. sub ModMap {
  2596.     local($module, $dir);
  2597.     open(MOD, "cvs -d $cvsroot $readonly co -c |") ||
  2598.     return &Error(1, "Can't do \"cvs co -c\"\n");
  2599.     undef %moduleToRepos;
  2600.     while(<MOD>) {
  2601.     if (/^(\S+)\s+(\S+)/) {
  2602.         $moduleToRepos{$1} = $2;
  2603.         $reposToModule{$2} = $1;
  2604.     }
  2605.     }
  2606.     close(MOD);
  2607. }
  2608.  
  2609. #
  2610. # Main
  2611. #
  2612. #
  2613. $SIG{'INT'} = Exit;
  2614. &initpwd();
  2615. $tmpfile = "#SCVS.$$";
  2616. $status = 0;
  2617. if (&Config) {
  2618.     exit(1);
  2619. }
  2620. $command = shift;
  2621. if (!defined($command)) {
  2622.     &Usage(@@options);
  2623.     exit(1);
  2624. }
  2625. printf("$command: %s\n", join(' ', @@ARGV)) if ($debug);
  2626.  
  2627. &ModMap();
  2628.  
  2629. if (($command eq "pack") || ($command eq "unpack")) {
  2630.     local(@@options) = ("l", $OPT_FALSE, *recurse, "Recurse on subdirectories");
  2631.     &Opt_Parse(*ARGV, @@options, $optFlags);
  2632.     $status = &PackCmd($command, @@ARGV);
  2633. } elsif (($command eq "checkout") || ($command eq "co")) {
  2634.     $command = "checkout";
  2635.     $status = &Checkout(@@ARGV);
  2636. } elsif ($command eq "unlock") {
  2637.     $status = &UnlockCmd(@@ARGV);
  2638. } elsif ($command eq "lock") {
  2639.     $status = &LockCmd(@@ARGV);
  2640.     undef(@@locks);
  2641. } elsif ($command eq "update") {
  2642.     $status = &UpdateCmd(1, @@ARGV);
  2643. } elsif ($command eq "done") {
  2644.     $status = &DoneCmd(@@ARGV);
  2645. } elsif (($command eq "commit") || ($command eq "ci")) {
  2646.     $status = &CommitCmd(@@ARGV);
  2647. } elsif ($command eq "who") {
  2648.     $status = &WhoCmd(@@ARGV);
  2649. } elsif ($command eq "add") {
  2650.     $status = &AddCmd(@@ARGV);
  2651. } elsif ($command eq "remove") {
  2652.     $status = &RemoveCmd(@@ARGV);
  2653. } elsif ($command eq "info") {
  2654.     $status = &InfoCmd(@@ARGV);
  2655. } elsif ($command eq "diff") {
  2656.     $status = &DiffCmd(@@ARGV);
  2657. } elsif (($command eq "status") || ($command eq "log")) {
  2658.     $status = &CvsCmd($command, @@ARGV);
  2659. } elsif (grep($command eq $_, @@cvsCmds)) {
  2660.     &System("cvs -d $cvsroot $cvsCmdArgs $readonly $command @@ARGV");
  2661.     $status = 0;
  2662. } else {
  2663.     printf("Bad command: $command\n");
  2664.     &Usage(@@options);
  2665.     exit(1);
  2666. }
  2667.  
  2668. # Unlock any modules we may have locked.
  2669.  
  2670. if ($#locks >= $[) {
  2671.     &Unlock(0, @@locks);
  2672. }
  2673. if ($status) {
  2674.     printf("$command command failed\n");
  2675. }
  2676. exit($status);
  2677. @
  2678.  
  2679.  
  2680. 1.21
  2681. log
  2682. @print 'D' when deleting link.  Ignore links starting with *.  Look for link
  2683. files that have been merged.  Checkout requires a list of modules. 
  2684. mine and others array not reinitialized for each module.  
  2685. -i won't tell you about other copies.
  2686. if SCVS is modified then UpdateInstalled updates the parent
  2687. remove should delete links that point to nowhere
  2688. @
  2689. text
  2690. @d7 1
  2691. a7 1
  2692. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.20 91/12/11 17:53:48 jhh Exp $ SPRITE (Berkeley)
  2693. d2045 1
  2694. d2150 1
  2695. @
  2696.  
  2697.  
  2698. 1.20
  2699. log
  2700. @-r option wasn't handled properly
  2701. @
  2702. text
  2703. @d7 1
  2704. a7 1
  2705. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.19 91/11/16 18:08:03 jhh Exp $ SPRITE (Berkeley)
  2706. d285 1
  2707. a285 2
  2708.                 printf(STDERR "Removing deleted link $1\n") 
  2709.                 if ($debug);
  2710. d301 10
  2711. d532 4
  2712. d547 2
  2713. d568 1
  2714. a568 1
  2715.     print(CO "$cvsCmdArgs\n");
  2716. d638 1
  2717. a638 1
  2718.     if (defined(%others)) {
  2719. d1273 6
  2720. a1278 3
  2721.         $new = readlink($link);
  2722.         if (!defined($new)) {
  2723.             return &Error(1, "Can't read link $link\n");
  2724. a1279 1
  2725.         s/$old/$new/;
  2726. d1315 2
  2727. d1329 4
  2728. d1338 1
  2729. a1338 1
  2730.     &UpdateCmd(0, "-q", @@files) == 0 || return 1;
  2731. d1389 2
  2732. a1390 1
  2733.         &System("cvs -d $cvsroot $cvsCmdArgs $readonly ci -f -m scvs links");
  2734. d1708 1
  2735. a1708 1
  2736.     if (-e $i) {
  2737. @
  2738.  
  2739.  
  2740. 1.19
  2741. log
  2742. @Commit committed everything, even if you gave it a list of files.
  2743. @
  2744. text
  2745. @d7 1
  2746. a7 1
  2747. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.18 91/11/14 22:49:25 jhh Exp $ SPRITE (Berkeley)
  2748. d42 2
  2749. a43 2
  2750.     "r", $OPT_TRUE, "*readonly", "Check out files read-only",
  2751.     "w", $OPT_FALSE, "*readonly", "Check out files read-write (default)",
  2752. d62 1
  2753. d514 1
  2754. a514 1
  2755.     $buffer = "cvs -d $cvsroot $cvsCmdArgs co $args";
  2756. @
  2757.  
  2758.  
  2759. 1.18
  2760. log
  2761. @allow clustering of options.  Check for invalid options.
  2762. @
  2763. text
  2764. @d7 1
  2765. a7 1
  2766. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.17 91/11/13 21:39:04 jhh Exp $ SPRITE (Berkeley)
  2767. d19 2
  2768. a20 2
  2769. #require "option.pl";
  2770. require "/sprite/src/lib/perl/option.pl";
  2771. d1340 1
  2772. a1340 1
  2773.     printf(STDERR "CommitDir $path $args $files\n") if ($debug);
  2774. d1368 1
  2775. a1368 1
  2776.     if (defined($files)) {
  2777. d1428 3
  2778. d1463 3
  2779. d2366 1
  2780. a2366 1
  2781.             $dirs{substr($i, 0, $index - 1)} .= "$tail "; 
  2782. @
  2783.  
  2784.  
  2785. 1.17
  2786. log
  2787. @better algorithm for determining module name.  Recomputes links
  2788. file in VerifyCurrent in case some links have been changed.
  2789. @
  2790. text
  2791. @d7 1
  2792. a7 1
  2793. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.16 91/11/04 22:20:08 jhh Exp Locker: jhh $ SPRITE (Berkeley)
  2794. d19 2
  2795. a20 1
  2796. require "option.pl";
  2797. d35 2
  2798. d50 1
  2799. a50 1
  2800. &Opt_Parse(*ARGV, @@options, $OPT_OPTIONS_FIRST);
  2801. d487 1
  2802. d504 1
  2803. a504 1
  2804.     &Opt_Parse(*modules, @@options, $OPT_OPTIONS_FIRST | $OPT_NO_SPACE);
  2805. d506 4
  2806. d648 5
  2807. a652 1
  2808.     &Opt_Parse(*args, @@options, $OPT_OPTIONS_FIRST);
  2809. d751 5
  2810. a755 1
  2811.     &Opt_Parse(*args, @@options, $OPT_OPTIONS_FIRST);
  2812. d911 1
  2813. a911 1
  2814.     &Opt_Parse(*names, @@options, $OPT_OPTIONS_FIRST | $OPT_NO_SPACE);
  2815. d913 4
  2816. d1049 1
  2817. a1049 1
  2818.     &Opt_Parse(*modules, @@options, $OPT_OPTIONS_FIRST); 
  2819. d1053 4
  2820. d1413 1
  2821. a1413 1
  2822.     &Opt_Parse(*names, @@options, $OPT_OPTIONS_FIRST | $OPT_NO_SPACE);
  2823. d1415 4
  2824. d1560 1
  2825. a1560 1
  2826.     &Opt_Parse(*names, @@options, $OPT_OPTIONS_FIRST | $OPT_NO_SPACE);
  2827. d1562 4
  2828. d1838 1
  2829. a1838 1
  2830.     &Opt_Parse(*modules, @@options, $OPT_OPTIONS_FIRST);
  2831. d1981 2
  2832. d1987 5
  2833. a1991 1
  2834.     &Opt_Parse(*modules, @@options, $OPT_OPTIONS_FIRST | $OPT_NO_SPACE);
  2835. d2093 5
  2836. a2097 1
  2837.     &Opt_Parse(*modules, @@options, $OPT_OPTIONS_FIRST | $OPT_NO_SPACE);
  2838. d2471 1
  2839. a2471 1
  2840.     &Opt_Parse(*ARGV, @@options, 0);
  2841. @
  2842.  
  2843.  
  2844. 1.16
  2845. log
  2846. @Chdir sometimes called with undefined arguments. If a subroutine
  2847. is called without parenthesis the @@_ array ends up being the
  2848. same as the parent's (it's incorrect anyway).
  2849. @
  2850. text
  2851. @d7 1
  2852. a7 1
  2853. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.15 91/11/04 21:12:46 jhh Exp $ SPRITE (Berkeley)
  2854. d788 1
  2855. a788 1
  2856.         printf("Can't find module name for dir $i\n"); 
  2857. d843 1
  2858. a843 1
  2859.     if ($status) {
  2860. d1194 1
  2861. d1224 26
  2862. d1316 1
  2863. a1316 1
  2864.     printf(STDERR "CommitDir $path\n") if ($debug);
  2865. d1400 6
  2866. d1426 1
  2867. a1426 1
  2868.     print("Committing modified directories.\n");
  2869. d1432 1
  2870. d1434 1
  2871. a1434 1
  2872.     $status = &Commit($i, $args, $files{$i});
  2873. d1471 1
  2874. a1471 1
  2875.     push(@@modules, ".");
  2876. d1481 3
  2877. d2235 3
  2878. d2307 1
  2879. a2307 1
  2880.     local(%dirs, $i, $index, $tail);
  2881. d2316 1
  2882. a2316 1
  2883.             if ($index != $[) {
  2884. d2332 6
  2885. d2472 1
  2886. a2472 1
  2887.     printf("$command failed\n");
  2888. @
  2889.  
  2890.  
  2891. 1.15
  2892. log
  2893. @better handling of -r flag.  Doesn't prune empty *.md directories of
  2894. known machine types.  Better parsing of names. 
  2895. @
  2896. text
  2897. @d7 1
  2898. a7 1
  2899. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.14 91/11/03 14:00:58 jhh Exp Locker: jhh $ SPRITE (Berkeley)
  2900. d670 1
  2901. a670 1
  2902.         $i = &GetModuleName;
  2903. d893 1
  2904. d932 1
  2905. a932 1
  2906.     @@targs = &GetCheckoutArgs;
  2907. d1248 1
  2908. a1248 1
  2909.     $module = &GetModuleName;
  2910. d1259 1
  2911. d1401 1
  2912. a1401 1
  2913.     &Chdir($pwd) == 0 || return 1; 
  2914. d1412 2
  2915. a1413 2
  2916.         $status = &UpdateInstalled;
  2917.         &Chdir($pwd) == 0 || return 1; 
  2918. d1448 1
  2919. a1448 1
  2920.         $i = &GetModuleName;
  2921. d1501 1
  2922. a1501 1
  2923.     $module = &GetModuleName;
  2924. d1786 1
  2925. a1786 1
  2926.     &GetCheckoutArgs;
  2927. d2198 1
  2928. a2198 1
  2929.     $reposDir = &ReadFile("CVS.adm/Repository");
  2930. d2308 6
  2931. d2366 1
  2932. a2366 1
  2933. &initpwd;
  2934. d2379 1
  2935. a2379 1
  2936. &ModMap;
  2937. @
  2938.  
  2939.  
  2940. 1.14
  2941. log
  2942. @creates 'root' symbolic link.  Update can handle subdirectories.
  2943. @
  2944. text
  2945. @d7 1
  2946. a7 1
  2947. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.13 91/10/31 13:08:52 jhh Exp Locker: jhh $ SPRITE (Berkeley)
  2948. d32 1
  2949. d39 2
  2950. a40 2
  2951.     "r", $OPT_FUNC, "CvsOpt1", "Check out files read-only",
  2952.     "w", $OPT_FUNC, "CvsOpt1", "Check out files read-write (default)",
  2953. d53 6
  2954. d115 6
  2955. d220 1
  2956. a220 1
  2957.         system("cvs -d $cvsroot add SCVS");
  2958. d222 2
  2959. a223 1
  2960.         system("cvs -d $cvsroot add -m\"scvs links\" SCVS/$linkFile");
  2961. d246 2
  2962. d250 44
  2963. a293 1
  2964.     if (open(UNPACK, "SCVS/$linkFile")) {
  2965. d361 1
  2966. a363 1
  2967.     local($empty) = 1;
  2968. d365 2
  2969. d372 1
  2970. a372 1
  2971.     $status = &AllSubdirs($path, "Prune");
  2972. d376 20
  2973. a399 4
  2974.     if ($#contents >= $[) {
  2975.     print "Found @@contents in $path\n" if ($debug);
  2976.     $empty = 0;
  2977.     }
  2978. d401 1
  2979. a401 1
  2980.     if ($empty) {
  2981. d405 1
  2982. a405 1
  2983.     system("rm -rf $tail");
  2984. d508 1
  2985. a508 1
  2986.     system("$buffer");
  2987. d528 1
  2988. a528 2
  2989.     printf("$buffer $i \n") if ($debug);
  2990.     system("$buffer $i");
  2991. d555 1
  2992. a555 1
  2993.         &Prune($i) == 0 || return &Error(1, "Prune of $i failed\n");
  2994. d783 1
  2995. a783 1
  2996.     if (! -d $i) {
  2997. d786 1
  2998. a786 1
  2999.         $module = &GetModuleName;
  3000. d840 1
  3001. a840 1
  3002.     push(@@mylocks, $i);
  3003. d868 2
  3004. a869 2
  3005.     local(@@dirs) = @@_;
  3006.     local(%files);
  3007. d880 1
  3008. d894 1
  3009. a894 1
  3010.     &Opt_Parse(*dirs, @@options, $OPT_OPTIONS_FIRST | $OPT_NO_SPACE);
  3011. d907 3
  3012. d912 1
  3013. a912 7
  3014.     if ($#dirs < $[) {
  3015.     push(@@dirs, ".");
  3016.     }
  3017.     if (! -d $dirs[0]) {
  3018.     $files{"."} = @@dirs;
  3019.     @@dirs = (".");
  3020.     }
  3021. d918 1
  3022. a918 1
  3023.     $status = &Lock("r", @@dirs); 
  3024. d925 4
  3025. a928 1
  3026.     foreach $i (@@dirs) {
  3027. d931 4
  3028. a934 13
  3029.     if (-e "SCVS/root/SCVS/$argFile") {
  3030.         @@targs = &ReadFile("SCVS/root/SCVS/$argFile", 1);
  3031.         chop(@@targs);
  3032.         print("targs = @@targs\n") if ($debug);
  3033.         if ($targs[1] =~ /(.*)-p(.*)/) {
  3034.         $targs[1] = "$1 $2";
  3035.         print("Found -p in args file\n") if ($debug);
  3036.         $prune = 1;
  3037.         }
  3038.     }
  3039.     $tmp = "$buffer $targs[0] update $args $targs[1] $files{$i}";
  3040.     printf("$tmp\n") if ($debug);
  3041.     system($tmp);
  3042. d940 2
  3043. a941 1
  3044.         if (&Prune($i)) {
  3045. d1041 16
  3046. a1056 11
  3047.         printf("Directory $i not found.\n");
  3048.         next module;
  3049.     }
  3050.     &Chdir($i) == 0 || return 1; 
  3051.     ($status, $modified) = &Changed($i);
  3052.     if ($status) {
  3053.         printf(STDERR "Unable to determine if $i module has changed.\n");
  3054.         $modified = 1;
  3055.     }
  3056.     if ($modified == 1) {
  3057.         printf("Do you wish to continue? [y/n] ");
  3058. d1058 9
  3059. a1066 6
  3060.         while(1) {
  3061.         $answer = <STDIN>;
  3062.         chop($answer);
  3063.         last prompt if ($answer eq "y");
  3064.         next module if ($answer eq "n");
  3065.         printf("Please answer with \"y\" or \"n\": ");
  3066. a1067 2
  3067.     } elsif ($modified == 1) {
  3068.         next module;
  3069. d1109 1
  3070. a1109 1
  3071.         system("rm -rf $i");
  3072. d1187 1
  3073. d1252 1
  3074. a1252 1
  3075.     $dir = &ReadFile("$installdir/$module/SCVS/CVS.adm/Repository", 1);
  3076. d1257 3
  3077. d1261 1
  3078. a1261 1
  3079.     &UpdateCmd(0, "-Q", @@files) == 0 || return 1;
  3080. d1280 1
  3081. d1312 1
  3082. a1312 1
  3083.         system("cvs -d $cvsroot $cvsCmdArgs ci -f -m scvs links");
  3084. d1315 5
  3085. a1319 1
  3086.     system("cvs -d $cvsroot $cvsCmdArgs ci -f -a $args");
  3087. d1339 2
  3088. a1340 1
  3089.     local($pwd, $i);
  3090. d1347 1
  3091. a1361 4
  3092.  
  3093.     if ($#names < $[) {
  3094.     push(@@names, ".");
  3095.     }
  3096. d1370 9
  3097. a1378 2
  3098.     if (! -d $names[0]) {
  3099.     $status = &Lock("w","."); 
  3100. d1382 7
  3101. a1388 17
  3102.     $status = &VerifyCurrent(".", *stale, *modified);
  3103.     if ($status) {
  3104.         return $status;
  3105.     }
  3106.     if ($#stale >= $[) {
  3107.         printf("Update your sources using \"scvs update\".\n");
  3108.         return $status;
  3109.     }
  3110.     $tmp = "cvs -d $cvsroot $cvsCmdArgs ci -f $args @@names";
  3111.     system($tmp);
  3112.     $status = &UpdateInstalled(@@names);
  3113.     } else {
  3114.     $status = &Lock("w",@@names); 
  3115.     if ($status) {
  3116.         return $status;
  3117.     }
  3118.     $pwd = $ENV{'PWD'};
  3119. d1390 14
  3120. a1403 2
  3121.     #
  3122.     # All the modules and their subdirectories must be up-to-date.
  3123. a1404 15
  3124. module:
  3125.     foreach $i (@@names) {
  3126.         &Chdir($i) == 0 || return 1; 
  3127.         $status = &VerifyCurrent($i, *stale, *modified);
  3128.         if ($status) {
  3129.         return $status;
  3130.         }
  3131.         &Chdir($pwd) == 0 || return 1; 
  3132.     }
  3133.     
  3134.     if ($#stale >= $[) {
  3135.         printf("Update your sources using \"scvs update\".\n");
  3136.         return $status;
  3137.     }
  3138.     
  3139. d1406 1
  3140. a1406 1
  3141.         print("Committing modified directories.\n");
  3142. a1407 3
  3143.     #
  3144.     # Commit all directories that were modified.
  3145.     #
  3146. d1410 1
  3147. a1410 1
  3148.         $status = &Commit($i, $args);
  3149. a1412 13
  3150.     if (defined($installdir)) {
  3151.         # 
  3152.         # Update the installed copy of the sources.
  3153.         #
  3154.         if (! $quiet) {
  3155.         print("Updating installed copies.\n");
  3156.         }
  3157.         foreach $i (@@modified) {
  3158.         &Chdir($i) == 0 || return 1; 
  3159.         $status = &UpdateInstalled;
  3160.         &Chdir($pwd) == 0 || return 1; 
  3161.         }
  3162.     }
  3163. d1537 2
  3164. a1538 1
  3165.         system("cvs -d $cvsroot add -m \"sym links\" $linkFile");
  3166. d1545 1
  3167. a1545 1
  3168.         system("cvs -d $cvsroot $cvsCmdArgs add $args $i");
  3169. d1559 1
  3170. a1559 1
  3171.             system("cvs -d $cvsroot add module");
  3172. d1622 1
  3173. a1622 1
  3174.         system("cvs -d $cvsroot $cvsCmdArgs remove $i");
  3175. d1671 1
  3176. a1680 1
  3177.     print("$path\n");
  3178. d1685 9
  3179. a1693 19
  3180.     system("cvs -d $cvsroot $cvsCmdArgs info ");
  3181.     if (-d "SCVS") {
  3182.     &Chdir("SCVS") == 0 || return 1;
  3183.     open(INFO, "cvs -d $cvsroot $cvsCmdArgs info |") ||
  3184.         return &Error(1, "Can't do cvs info on $path: $!\n");
  3185.     while(<INFO>) {
  3186.         if (/^[UMC]\s+$linkFile/) {
  3187.         $diff = 1;
  3188.         last;
  3189.         } elsif (/^[AD]\s+$linkFile/) {
  3190.         $cat = 1;
  3191.         last;
  3192.         }
  3193.     }
  3194.     close(INFO);
  3195.     if ($diff) {
  3196.         local(%updated);
  3197.         open(INFO, "cvs -d $cvsroot diff $linkFile |") ||
  3198.         return &Error(1, "Can't do cvs diff on $path/$linkFile: $!\n");
  3199. d1695 6
  3200. a1700 25
  3201.         if (/^>\s+([^*]\S+)/) {
  3202.             printf("A %s\@@\n", $1);
  3203.         } elsif (/^>\s+[*](\S+)/) {
  3204.             printf("R %s\@@\n", $1);
  3205.             delete $updated{$1};
  3206.         } elsif (/^<\s+([^*]\S+)/) {
  3207.             $updated{$1} = 1;
  3208.         } elsif (/^<\s+[*](\S+)/) {
  3209.             printf("D %s\@@\n", $1);
  3210.         }
  3211.         }
  3212.         close(INFO);
  3213.         foreach $i (keys %updated) {
  3214.         printf("U %s\@@\n", $i);
  3215.         }
  3216.     }
  3217.     if ($cat) {
  3218.         open(INFO, "$linkFile") ||
  3219.         return &Error(1, "Open of $linkFile failed: $!\n");
  3220.         while(<INFO>) {
  3221.         next if (/^#/);
  3222.         if (/^([^*]\S+)/) {
  3223.             printf("A %s\@@\n", $1);
  3224.         } elsif (/^([*]\S+)/) {
  3225.             printf("R %s\@@\n", $1);
  3226. d1704 39
  3227. a1743 1
  3228.     &Chdir($pwd) == 0 || return 1;
  3229. a1744 3
  3230.     if (($recurse) && ($#files < $[)) {
  3231.     $status = &AllSubdirs($path, "Info");
  3232.     }
  3233. d1758 2
  3234. a1759 1
  3235.     local(@@modules) = @@_;
  3236. d1763 1
  3237. a1763 1
  3238.     local(@@targs);
  3239. d1768 2
  3240. a1769 1
  3241.     print "@@modules\n" if ($debug);
  3242. d1771 5
  3243. a1775 13
  3244.     if ($#modules < $[) {
  3245.     push(@@modules, ".");
  3246.     }
  3247.     if (-e "SCVS/root/SCVS/$argFile") {
  3248.     @@targs = &ReadFile("SCVS/root/SCVS/$argFile", 1);
  3249.     if ($targs[1] =~ /(.*)-p(.*)/) {
  3250.         $targs[1] = "$1 $2";
  3251.     }
  3252.     chop($targs[0]);
  3253.     $cvsCmdArgs .= $targs[0];
  3254.     }
  3255.     if (! -d $modules[0]) {
  3256.     $status = &Lock("r","."); 
  3257. d1779 7
  3258. a1785 3
  3259.     system("cvs -d $cvsroot $cvsCmdArgs info @@modules");
  3260.     } else {
  3261.     $status = &Lock("r",@@modules);
  3262. d1789 1
  3263. a1789 10
  3264.     $pwd = $ENV{'PWD'};
  3265.     foreach $i (@@modules) {
  3266.         printf("InfoCmd %i\n") if ($debug);
  3267.         &Chdir($i) == 0 || return 1; 
  3268.         $status = &Info($i);
  3269.         if ($status) {
  3270.         return $status;
  3271.         }
  3272.         &Chdir($pwd) == 0 || return 1; 
  3273.     }
  3274. d1828 1
  3275. a1828 1
  3276.     open(DIFF, "cvs -d $cvsroot status $file |") ||
  3277. d1838 1
  3278. a1838 1
  3279.     system("cvs -d $cvsroot $cvsCmdArgs diff $version $args $file");
  3280. d1973 1
  3281. a1973 1
  3282.     system("cvs -d $cvsroot $cvsCmdArgs $command");
  3283. d2026 3
  3284. a2028 3
  3285.     $tmp = "cvs -d $cvsroot $cvsCmdArgs $command $cvsargs @@modules";
  3286.     print "$tmp\n" if ($debug);
  3287.     system($tmp);
  3288. d2130 1
  3289. a2130 1
  3290.     return &Error(undef, "Open of $file failed: $!\n");
  3291. d2187 1
  3292. d2191 1
  3293. d2193 1
  3294. d2223 72
  3295. d2308 1
  3296. a2308 1
  3297.     return &Error(1, "Chdir to %s from %s failed: $!\nFile %s Line %s", 
  3298. d2315 14
  3299. d2341 1
  3300. a2341 1
  3301.     open(MOD, "cvs -d $cvsroot co -c |") ||
  3302. d2404 1
  3303. a2404 1
  3304.     system("cvs -d $cvsroot $cvsCmdArgs $command @@ARGV");
  3305. @
  3306.  
  3307.  
  3308. 1.13
  3309. log
  3310. @got rid of print
  3311. @
  3312. text
  3313. @d7 1
  3314. a7 1
  3315. # $Header: /sprite/src/cmds/scvs/RCS/scvs,v 1.11 91/10/31 12:05:01 jhh Exp Locker: mgbaker $ SPRITE (Berkeley)
  3316. d54 10
  3317. d317 4
  3318. a320 6
  3319.     foreach $i (readdir(THISDIR)) {
  3320.     next if ($i eq ".");
  3321.     next if ($i eq "..");
  3322.     next if ($i eq "CVS.adm");
  3323.     next if ($i eq "SCVS");
  3324.     print "Found $i in $path\n" if ($debug);
  3325. a321 1
  3326.     last;
  3327. d334 21
  3328. d469 1
  3329. a469 1
  3330.     print(CO "$args\n");
  3331. d482 3
  3332. a587 3
  3333.     if (!defined(%modMap)) {
  3334.     &ModMap;
  3335.     }
  3336. d600 1
  3337. a600 1
  3338.     if (!defined($modMap{$i})) {
  3339. d605 1
  3340. a605 1
  3341.     $cvsdir = "$cvsroot/$modMap{$i}/SCVS";
  3342. d683 1
  3343. a683 1
  3344.     local(@@modules) = @@_;
  3345. d695 1
  3346. d697 3
  3347. a699 3
  3348.     print("Lock $type @@modules\n") if ($debug);
  3349.     if (!defined(%modMap)) {
  3350.     &ModMap;
  3351. d701 12
  3352. a712 8
  3353.     if ($#modules < $[) {
  3354.     push(@@modules, ".");
  3355.     }
  3356. module:
  3357.     foreach $i (@@modules) {
  3358.     if ($i eq ".") {
  3359.         $i = &GetModuleName;
  3360.         if (!defined($i)) {
  3361. d714 1
  3362. a714 1
  3363.         next module;
  3364. d717 2
  3365. a718 1
  3366.     if (!defined($modMap{$i})) {
  3367. d721 1
  3368. a721 1
  3369.         next module;
  3370. d723 1
  3371. a723 1
  3372.     $cvsdir = "$cvsroot/$modMap{$i}/SCVS";
  3373. d739 1
  3374. a739 1
  3375.             next module;
  3376. d792 3
  3377. a794 2
  3378.     local(@@names) = @@_;
  3379.     local($buffer, $i, $cvsdir, $date, %count, %dates);
  3380. d797 1
  3381. a797 1
  3382.     local($pwd);
  3383. d802 2
  3384. d817 1
  3385. a817 1
  3386.     &Opt_Parse(*names, @@options, $OPT_OPTIONS_FIRST | $OPT_NO_SPACE);
  3387. d820 2
  3388. d832 16
  3389. a847 2
  3390.     if ($#names < $[) {
  3391.     push(@@names, ".");
  3392. d849 13
  3393. a861 5
  3394.     if (! -d $names[0]) {
  3395.     if ($lock) {
  3396.         $status = &Lock("r","."); 
  3397.         if ($status) {
  3398.         return $status;
  3399. d864 1
  3400. a864 1
  3401.     $tmp = "$buffer update $args @@names";
  3402. d867 3
  3403. a869 12
  3404.     $recurse = 0;
  3405.     &Unpack(".") == 0 ||
  3406.         return &Error(1, "Unpack of current directory failed.\n");
  3407.     } else {
  3408.     #
  3409.     # Lock the modules.
  3410.     #
  3411.     if ($lock) {
  3412.         $status = &Lock("r", @@names); 
  3413.         if ($status) {
  3414.         return $status;
  3415.         }
  3416. d871 3
  3417. a873 20
  3418.     $pwd = $ENV{'PWD'};
  3419. module: 
  3420.     foreach $i (@@names) {
  3421.         $prune = 0;
  3422.         &Chdir($i) == 0 || return 1; 
  3423.         if (-e "SCVS/$argFile") {
  3424.         local(@@targs);
  3425.         @@targs = &ReadFile("SCVS/$argFile", 1);
  3426.         if ($targs[1] =~ /(.*)-p(.*)/) {
  3427.             $targs[1] = "$1 $2";
  3428.             $prune = 1;
  3429.         }
  3430.         chop($targs[0]);
  3431.         chop($targs[1]);
  3432.         $tmp = "$buffer $targs[0] update $args $targs[1]";
  3433.         printf("$tmp\n") if ($debug);
  3434.         }
  3435.         system($tmp);
  3436.         if (&Unpack($i)) {
  3437.         printf(STDERR "Unpack of $i failed.\n");
  3438. a875 8
  3439.         if ($prune) {
  3440.         if (&Prune($i)) {
  3441.             printf(STDERR "Prune of $i failed.\n");
  3442.             $status = 1;
  3443.         }
  3444.         }
  3445.  
  3446.         &Chdir($pwd) == 0 || return 1; 
  3447. d877 1
  3448. d1168 1
  3449. a1168 1
  3450.     local($saveArgs) = $cvsCmdArgs;
  3451. d1171 6
  3452. a1176 2
  3453.     $cvsCmdArgs = "-r";
  3454.     $dir = &ReadFile("CVS.adm/Repository", 1);
  3455. a1183 1
  3456.     $cvsCmdArgs = $saveArgs;
  3457. d1261 1
  3458. d1268 2
  3459. d1280 9
  3460. a1288 2
  3461.     $args .= " -q";
  3462.     if (-f $names[0]) {
  3463. d1329 3
  3464. d1338 11
  3465. a1348 2
  3466.         last if ($status);
  3467.         if (defined($installdir)) {
  3468. d1350 1
  3469. a1350 1
  3470.         last if ($status);
  3471. a1351 1
  3472.         &Chdir($pwd) == 0 || return 1; 
  3473. a1373 3
  3474.     if (!defined(%modMap)) {
  3475.     &ModMap;
  3476.     }
  3477. d1392 1
  3478. a1392 1
  3479.     if (!defined($modMap{$i})) {
  3480. d1397 1
  3481. a1397 1
  3482.     $cvsdir = $cvsroot . "/" . $modMap{$i};
  3483. d1546 7
  3484. a1552 3
  3485.         printf("$i still exists, moving to $i.old\n");
  3486.         if (!rename("$i", "$i.old")) {
  3487.         printf("Rename failed: $!\n");
  3488. d1619 1
  3489. d1624 1
  3490. a1624 1
  3491.     system("cvs -d $cvsroot $cvsCmdArgs info");
  3492. d1627 1
  3493. a1627 1
  3494.     open(INFO, "cvs -d $cvsroot info |") ||
  3495. d1695 1
  3496. d1705 9
  3497. a1713 1
  3498.     if (-f $modules[0]) {
  3499. d1863 1
  3500. a1863 1
  3501.     if (-f $modules[0]) {
  3502. d1965 1
  3503. a1965 1
  3504.     if (-f $modules[0]) {
  3505. d2112 2
  3506. a2113 1
  3507. # Gets the module name from the name in CVS.adm/Repository and %dirMap.
  3508. d2117 1
  3509. a2117 1
  3510. # Side effects:  
  3511. d2120 2
  3512. a2121 1
  3513.     local($dir);
  3514. d2123 36
  3515. a2158 20
  3516.     if (!defined(%dirMap)) {
  3517.     &ModMap;
  3518.     }
  3519.     $dir = &ReadFile("CVS.adm/Repository");
  3520.     chop($dir);
  3521.     printf("$dir\n") if ($debug);
  3522.     if (!defined($dir)) {
  3523.     return undef;
  3524.     }
  3525.     while($dir ne "") {
  3526.     if (defined($dirMap{$dir})) {
  3527.         printf("Module $dirMap{$dir}\n") if ($debug);
  3528.         return $dirMap{$dir};
  3529.     }
  3530.     $index = rindex($dir, '/');
  3531.     if ($index < $[) {
  3532.         last;
  3533.         return $dir;
  3534.     }
  3535.     $dir = substr($dir, 0, $index);
  3536. d2160 1
  3537. a2160 1
  3538.     return $dir;
  3539. a2161 1
  3540.  
  3541. d2175 5
  3542. a2179 3
  3543.     &chdir($_[0]) ||
  3544.     return &Error(1, "Chdir to %s from %s failed: $!\n", 
  3545.         $_[0], $ENV{'PWD'});
  3546. d2191 1
  3547. a2191 1
  3548. # Side effects:  The %modMap and %dirMap are filled in.
  3549. d2198 1
  3550. a2198 1
  3551.     undef %modMap;
  3552. d2201 2
  3553. a2202 2
  3554.         $modMap{$1} = $2;
  3555.         $dirMap{$2} = $1;
  3556. d2225 2
  3557. @
  3558.  
  3559.  
  3560. 1.12
  3561. log
  3562. @updates to non-existent files didn't work
  3563. @
  3564. text
  3565. @a795 1
  3566.     print("name = $names[0]\n");
  3567. @
  3568.  
  3569.  
  3570. 1.11
  3571. log
  3572. @fixed a couple of bugs concerning updating of installed sources
  3573. and locking.
  3574. @
  3575. text
  3576. @d7 1
  3577. a7 1
  3578. # $Header: /local/src/cmds/scvs/RCS/scvs,v 1.10 91/10/08 17:21:06 jhh Exp $ SPRITE (Berkeley)
  3579. a778 1
  3580.  
  3581. d796 2
  3582. a797 1
  3583.     if (-f $names[0]) {
  3584. @
  3585.  
  3586.  
  3587. 1.10
  3588. log
  3589. @added update of installed sources
  3590. @
  3591. text
  3592. @d7 1
  3593. a7 1
  3594. # $Header: /local/src/cmds/scvs/RCS/scvs,v 1.7 91/09/10 23:20:03 jhh Exp Locker: jhh $ SPRITE (Berkeley)
  3595. d36 1
  3596. a36 1
  3597.     "v", $OPT_TRUE, *verbose, "Verbose",
  3598. d378 1
  3599. d384 1
  3600. d396 5
  3601. d402 7
  3602. a412 8
  3603.     # Put together the "cvs co" command.
  3604.  
  3605.     $buffer = "cvs -d $cvsroot $cvsCmdArgs co";
  3606.  
  3607.     if (($cvsargs =~ /-r/) || ($cvsargs =~ /-D/)) {
  3608.     $cvsargs .= "-f ";
  3609.     }
  3610.     $buffer .= " $cvsargs";
  3611. d438 4
  3612. a441 3
  3613.     printf(CO "# This file contains the arguments given when this\n");
  3614.     printf(CO "# module was checked out.\n");
  3615.     printf(CO "%s\n", $cvsargs);
  3616. d792 1
  3617. a792 1
  3618.     $buffer = "cvs -d $cvsroot $cvsCmdArgs update ";
  3619. d804 1
  3620. a804 1
  3621.     $tmp = "$buffer $args @@names";
  3622. a823 1
  3623.         local($targs);
  3624. d825 11
  3625. a835 4
  3626.         $targs = &ReadFile("SCVS/$argFile", 1);
  3627.         if ($targs =~ /(.*)-p(.*)/) {
  3628.         $targs = "$1 $2";
  3629.         $prune = 1;
  3630. a836 2
  3631.         $tmp = "$buffer $args $targs";
  3632.         printf("$tmp\n") if ($debug);
  3633. d1046 2
  3634. a1047 1
  3635.     @@subdirs = grep((-d) && (!/^\./) && ($_ ne 'CVS.adm'), readdir(THISDIR));
  3636. d1143 1
  3637. d1202 1
  3638. a1202 1
  3639.         system("cvs -d $cvsroot $cvsCmdArgs ci -m scvs links");
  3640. d1205 1
  3641. a1205 1
  3642.     system("cvs -d $cvsroot $cvsCmdArgs ci -a $args");
  3643. d1261 1
  3644. a1261 1
  3645.     $tmp = "cvs -d $cvsroot $cvsCmdArgs ci $args @@names";
  3646. d1296 4
  3647. a1299 2
  3648.         $status = &UpdateInstalled;
  3649.         last if ($status);
  3650. d1378 9
  3651. a1386 1
  3652.     local($module); 
  3653. d1436 1
  3654. a1436 1
  3655.         system("cvs -d $cvsroot $cvsCmdArgs add $i");
  3656. a1570 1
  3657.     print("$path\n");
  3658. d2098 1
  3659. a2098 1
  3660.         $dir, $ENV{'PWD'});
  3661. @
  3662.  
  3663.  
  3664. 1.9
  3665. log
  3666. @added read and write locks
  3667. @
  3668. text
  3669. @d96 2
  3670. d351 3
  3671. a353 1
  3672.     $cvsargs .= "@@_ ";
  3673. d694 1
  3674. a694 1
  3675.             if (($prevType eq "w") && ($type eq "r")) {
  3676. d696 3
  3677. a705 1
  3678.             push(@@prevLocks, $_);
  3679. d707 1
  3680. d736 1
  3681. a736 1
  3682. # UpdateCmd(@@names)
  3683. d750 1
  3684. d759 1
  3685. d775 1
  3686. d780 1
  3687. a780 1
  3688.     $cvsargs .= "-d ";
  3689. d783 1
  3690. a783 1
  3691.     $cvsargs .= "-l ";
  3692. d791 5
  3693. a795 3
  3694.     $status = &Lock("r","."); 
  3695.     if ($status) {
  3696.         return $status;
  3697. d797 1
  3698. a797 1
  3699.     $tmp = "$buffer $cvsargs @@names";
  3700. d807 5
  3701. a811 3
  3702.     $status = &Lock("r", @@names); 
  3703.     if ($status) {
  3704.         return $status;
  3705. d824 1
  3706. a824 1
  3707.         $tmp = "$buffer $cvsargs $targs";
  3708. d833 1
  3709. a833 1
  3710.             printf(STDERR "Unpack of $i failed.\n");
  3711. d1115 32
  3712. d1163 1
  3713. d1217 1
  3714. d1229 1
  3715. d1234 1
  3716. a1234 1
  3717.     $cvsargs .= " -q";
  3718. d1248 1
  3719. a1248 1
  3720.     $tmp = "cvs -d $cvsroot $cvsCmdArgs ci $cvsargs @@names";
  3721. d1250 1
  3722. d1281 3
  3723. a1283 1
  3724.         $status = &Commit($i, $cvsargs);
  3725. d2136 1
  3726. a2136 1
  3727.     $status = &UpdateCmd(@@ARGV);
  3728. @
  3729.  
  3730.  
  3731. 1.8
  3732. log
  3733. @added diff -R, and cleaned up a few things.
  3734. @
  3735. text
  3736. @d31 1
  3737. a31 1
  3738. $userFile = "SCVS.users";
  3739. d38 6
  3740. d45 1
  3741. d50 1
  3742. d93 3
  3743. a95 1
  3744.         $cvsroot = $1;
  3745. d334 1
  3746. d372 2
  3747. a373 1
  3748.     local($force, $prune) = (0, 1);
  3749. a375 1
  3750.     "f", $OPT_TRUE, *force, "Force tags to match.",
  3751. d377 2
  3752. d391 4
  3753. d397 1
  3754. a397 1
  3755.     $buffer = "cvs -d $cvsroot co";
  3756. d399 1
  3757. a399 1
  3758.     if ($force) {
  3759. d413 3
  3760. a415 3
  3761.     printf("$buffer" . " $i" . "\n") if ($debug);
  3762.     system("$buffer" . " $i");
  3763.     
  3764. d486 8
  3765. a493 2
  3766.     if (!rename("$repos/$tmpfile", "$repos/$userFile")) {
  3767.         printf("Rename of $repos/$tmpfile to $repos/$userFile failed:$!\n");
  3768. a494 1
  3769.         next module;
  3770. d507 7
  3771. a513 1
  3772. # UnlockCmd(@@modules)
  3773. d515 11
  3774. a525 2
  3775. # Remove the lock files for a list of modules.  This is useful if something
  3776. # crashed and left the lock files.
  3777. d527 6
  3778. d538 2
  3779. a539 1
  3780. sub UnlockCmd {
  3781. d543 1
  3782. d545 1
  3783. d566 4
  3784. a569 5
  3785.     $cvsdir = $cvsroot . "/" . $modMap{$i};
  3786.     $lock = "$cvsdir" . "/" . "LOCK.scvs";
  3787.     if (-e $lock) {
  3788.         unlink($lock) ||
  3789.         ($status = &Error(1, "Can't remove $lock: $!\n"));
  3790. d571 57
  3791. a627 2
  3792.     }
  3793.     return $status;
  3794. d629 1
  3795. d632 1
  3796. a632 1
  3797. # LockCmd(@@modules)
  3798. d642 2
  3799. a643 1
  3800. sub LockCmd {
  3801. d651 5
  3802. d657 1
  3803. d678 37
  3804. a714 13
  3805.     $cvsdir = $cvsroot . "/" . $modMap{$i};
  3806.     if (-f "$cvsdir/LOCK.scvs") {
  3807.         $name = &ReadFile("$cvsdir/LOCK.scvs", 1);
  3808.         if (defined($name)) {
  3809.         printf("$i module is already locked by $name\n");
  3810.         $status = 1;
  3811.         last module;
  3812.         }
  3813.     }
  3814.     $status = &WriteFile("$cvsdir/LOCK.scvs", $user);
  3815.     if ($status) {
  3816.         printf(STDERR "Lock of $i module failed\n");
  3817.         last module;
  3818. d717 1
  3819. a717 1
  3820.     push(@@lockFiles, "$cvsdir/LOCK.scvs");
  3821. d720 1
  3822. a720 1
  3823.     if (&UnlockCmd(@@mylocks)) {
  3824. d724 1
  3825. a724 1
  3826.     push(@@locks, @@lockFiles);
  3827. d775 1
  3828. a775 1
  3829.     $buffer = "cvs -d $cvsroot update ";
  3830. d781 1
  3831. a781 1
  3832.     $status = &LockCmd("."); 
  3833. d795 1
  3834. a795 1
  3835.     $status = &LockCmd(@@names); 
  3836. d912 1
  3837. a912 1
  3838.     $status = &LockCmd(@@modules); 
  3839. d1142 1
  3840. a1142 1
  3841.         system("cvs -d $cvsroot ci -m scvs links");
  3842. d1145 1
  3843. a1145 1
  3844.     system("cvs -d $cvsroot ci -a $args");
  3845. d1187 1
  3846. a1187 1
  3847.     $status = &LockCmd("."); 
  3848. d1199 1
  3849. a1199 1
  3850.     $tmp = "cvs -d $cvsroot ci $cvsargs @@names";
  3851. d1202 1
  3852. a1202 1
  3853.     $status = &LockCmd(@@names); 
  3854. d1262 1
  3855. a1262 1
  3856.     $status = &LockCmd(@@modules); 
  3857. a1315 4
  3858.     $status = &LockCmd("."); 
  3859.     if ($status) {
  3860.     return $status;
  3861.     }
  3862. d1361 1
  3863. a1361 1
  3864.         system("cvs -d $cvsroot add $i");
  3865. a1409 5
  3866.     $status = &LockCmd("."); 
  3867.     if ($status) {
  3868.     return $status;
  3869.     }
  3870.  
  3871. d1434 1
  3872. a1434 1
  3873.         system("cvs -d $cvsroot remove $i");
  3874. d1497 1
  3875. a1497 1
  3876.     system("cvs -d $cvsroot info");
  3877. d1578 1
  3878. a1578 1
  3879.     $status = &LockCmd("."); 
  3880. d1582 1
  3881. a1582 1
  3882.     system("cvs -d $cvsroot info @@modules");
  3883. d1584 1
  3884. a1584 1
  3885.     $status = &LockCmd(@@modules);
  3886. d1646 1
  3887. a1646 1
  3888.     system("cvs -d $cvsroot diff $version $args $file");
  3889. d1728 1
  3890. a1728 1
  3891.     $status = &LockCmd("."); 
  3892. d1736 1
  3893. a1736 1
  3894.     $status = &LockCmd(@@modules);
  3895. d1781 1
  3896. a1781 1
  3897.     system("cvs -d $cvsroot $command");
  3898. d1830 1
  3899. a1830 1
  3900.     $status = &LockCmd("."); 
  3901. d1834 1
  3902. a1834 1
  3903.     $tmp = "cvs -d $cvsroot $command $cvsargs @@modules";
  3904. d1838 1
  3905. a1838 1
  3906.     $status = &LockCmd(@@modules); 
  3907. d2081 1
  3908. a2081 1
  3909.     $status = &LockCmd(getlogin, @@ARGV);
  3910. d2102 1
  3911. a2102 1
  3912.     system("cvs -d $cvsroot $command @@ARGV");
  3913. d2112 2
  3914. a2113 2
  3915. foreach $i (@@locks) {
  3916.     unlink($i);
  3917. @
  3918.  
  3919.  
  3920. 1.7
  3921. log
  3922. @pruning is now done by scvs since it knows about SCVS subdirs.
  3923. uses opendir, readdir, closedir
  3924. @
  3925. text
  3926. @d1 1
  3927. a1 1
  3928. #! /sprite/cmds/perl -w
  3929. d7 1
  3930. a7 1
  3931. # $Header: /local/src/cmds/scvs/RCS/scvs,v 1.3 91/09/02 12:53:04 jhh Exp Locker: jhh $ SPRITE (Berkeley)
  3932. a38 1
  3933.  
  3934. d68 1
  3935. a68 1
  3936.     &Chdir("..") && return 1;
  3937. d93 1
  3938. a93 1
  3939.     &Chdir("$pwd") && return 1;
  3940. d117 1
  3941. a117 1
  3942.     &Chdir($dir) && return 1; 
  3943. d126 1
  3944. a126 1
  3945.     &Chdir($pwd) && return 1; 
  3946. d259 4
  3947. a262 5
  3948.     open(REP, "$_[0]/CVS.adm/Repository") ||
  3949.     return &Error(undef, "Open of $_[0]/CVS.adm/Repository failed: $!\n");
  3950.     $tmp = <REP>;
  3951.     if (!defined($tmp)) {
  3952.     return undef;
  3953. d264 1
  3954. a264 3
  3955.     close(REP);
  3956.     chop($tmp);
  3957.     return $cvsroot . "/" . $tmp; 
  3958. d307 1
  3959. a307 1
  3960.     &Chdir("..") && return 1;
  3961. d313 27
  3962. a361 1
  3963.     local($args) = "";
  3964. d366 7
  3965. d375 2
  3966. a376 1
  3967.     &Opt_Parse(*modules, @@options, $OPT_OPTIONS_FIRST);
  3968. a381 18
  3969.     # Store all the arguments to "cvs co" in @@args for later.
  3970.  
  3971.     while ($i = shift(@@modules)) {
  3972.     last if ($i !~ /^-/);
  3973.     if (($i eq "-r") || ($i eq "-D")) {
  3974.         $args .= " $i";
  3975.         $i = shift(@@modules);
  3976.         $args .= " \"$i\"";
  3977.         $force = 1;
  3978.         next;
  3979.     }
  3980.     if ($i eq "-e") {
  3981.         $args .= " $i";
  3982.         $i = shift(@@modules);
  3983.     }
  3984.     $args .= " $i";
  3985.     }
  3986.     unshift(@@modules, $i) if (defined($i));
  3987. d383 1
  3988. a383 1
  3989.     $args .= " -f";
  3990. d385 1
  3991. a385 4
  3992. #    if ($prune) {
  3993. #    $args .= " -p -e SCVS";
  3994. #    }
  3995.     $buffer .= " $args";
  3996. a386 4
  3997.  
  3998.     if ($prune) {
  3999.     $args .= " -p";
  4000.     }
  4001. d413 1
  4002. a413 1
  4003.     printf(CO "%s\n", $args);
  4004. d416 1
  4005. a416 1
  4006.     &Chdir($i) && return 1; 
  4007. d419 1
  4008. a419 1
  4009.     &Unpack($i) && return &Error("Unpack of $i failed\n");
  4010. d423 1
  4011. a423 1
  4012.         &Prune($i) && return &Error("Prune of $i failed\n");
  4013. d426 1
  4014. a426 1
  4015.     &Chdir($pwd) && return 1; 
  4016. d439 1
  4017. a439 1
  4018.         return &Error("Open of $repos/$userFile failed: $!\n");
  4019. a614 1
  4020.     local($args) = "";
  4021. d621 13
  4022. a633 1
  4023.      );
  4024. d637 2
  4025. a638 3
  4026.     while ($i = shift(@@names)) {
  4027.     last if ($i !~ /^-/);
  4028.     $args .= " $i";
  4029. d640 2
  4030. a641 4
  4031.     unshift(@@names, $i) if (defined($i));
  4032.  
  4033.     if ($buildDirs) {
  4034.     $args .= "-d ";
  4035. d653 1
  4036. a653 1
  4037.     $tmp = "$buffer $args @@names";
  4038. d657 1
  4039. a657 1
  4040.     &Unpack(".") &&
  4041. d672 1
  4042. a672 1
  4043.         &Chdir($i) && return 1; 
  4044. d678 1
  4045. a678 1
  4046.         $tmp = "$buffer $args $targs";
  4047. d692 1
  4048. a692 1
  4049.         &Chdir($pwd) && return 1; 
  4050. d774 2
  4051. a775 1
  4052.     &Opt_Parse(*modules, @@options, 0); 
  4053. d791 1
  4054. a791 1
  4055.     &Chdir($i) && return 1; 
  4056. d848 1
  4057. a848 1
  4058.     &Chdir($pwd) && return 1; 
  4059. d895 1
  4060. a895 1
  4061.     &Chdir($dir) && return 1; 
  4062. d897 1
  4063. a897 1
  4064.     &Chdir($pwd) && ($status = 1); 
  4065. d938 1
  4066. a938 1
  4067.     return &Error("Can't get info for $path: $!\n");
  4068. a1034 1
  4069.     local(@@options) = ("l", $OPT_FALSE, *recurse, "Don't recurse on subdirs");
  4070. d1038 7
  4071. a1044 1
  4072.     local($args) = "";
  4073. d1047 2
  4074. a1048 1
  4075.     &Opt_Parse(*names, @@options, 0);
  4076. a1049 11
  4077.     while ($i = shift(@@names)) {
  4078.     last if ($i !~ /^-/);
  4079.     if ($i =~ /^-[mr]/) {
  4080.         $args .= " $i";
  4081.         $i = shift(@@names);
  4082.         $args .= " \"$i\"";
  4083.         next;
  4084.     }
  4085.     $args .= " $i";
  4086.     }
  4087.     unshift(@@names, $i) if (defined($i));
  4088. d1053 1
  4089. a1053 1
  4090.     $args .= " -q";
  4091. d1059 9
  4092. a1067 1
  4093.     $tmp = "cvs -d $cvsroot ci $args " . join(' ', @@names);
  4094. d1081 1
  4095. a1081 1
  4096.         &Chdir($i) && return 1; 
  4097. d1086 1
  4098. a1086 1
  4099.         &Chdir($pwd) && return 1; 
  4100. d1098 2
  4101. a1099 2
  4102.         &Chdir($i) && return 1; 
  4103.         $status = &Commit($i, $args);
  4104. d1101 1
  4105. a1101 1
  4106.         &Chdir($pwd) && return 1; 
  4107. d1224 1
  4108. a1224 1
  4109.         &Chdir("SCVS") && return 1; 
  4110. d1227 1
  4111. a1227 1
  4112.         &Chdir($pwd) && return 1; 
  4113. d1242 1
  4114. a1242 1
  4115.             &Chdir("$i/SCVS") && return 1; 
  4116. d1248 1
  4117. a1248 1
  4118.             &Chdir($pwd) && return 1; 
  4119. d1300 6
  4120. a1305 3
  4121.         printf("$i still exists.\n");
  4122.         $status = 1;
  4123.         next name;
  4124. d1364 1
  4125. d1371 6
  4126. d1423 1
  4127. a1423 3
  4128.     } else {
  4129.     printf("$path\n");
  4130.     system("cvs -d $cvsroot info");
  4131. d1425 1
  4132. a1425 1
  4133.     if ($recurse) {
  4134. d1447 3
  4135. a1449 1
  4136.     &Opt_Parse(*modules, @@options, 0);
  4137. a1450 1
  4138.     print join(' ', @@modules) . "\n";
  4139. d1454 108
  4140. a1561 3
  4141.     $status = &LockCmd(@@modules); 
  4142.     if ($status) {
  4143.     return $status;
  4144. d1563 33
  4145. a1595 1
  4146.     $pwd = $ENV{'PWD'};
  4147. d1597 17
  4148. a1613 4
  4149.     foreach $i (@@modules) {
  4150.     printf("InfoCmd %i\n") if ($debug);
  4151.     &Chdir($i) && return 1; 
  4152.     $status = &Info($i);
  4153. d1617 11
  4154. a1627 1
  4155.     &Chdir($pwd) && return 1; 
  4156. a1681 1
  4157.     local(@@options) = ("l", $OPT_FALSE, *recurse, "Don't recurse on subdirs");
  4158. d1684 14
  4159. d1700 2
  4160. a1701 7
  4161.     &Opt_Parse(*modules, @@options, 0);
  4162.  
  4163.     while ($i = shift(@@names)) {
  4164.     last if ($i !~ /^-/);
  4165.     $args .= " $i";
  4166.     }
  4167.     unshift(@@names, $i) if (defined($i));
  4168. d1706 13
  4169. a1718 6
  4170.  
  4171.     $status = &LockCmd(@@modules); 
  4172.     if ($status) {
  4173.     return $status;
  4174.     }
  4175.  
  4176. d1720 5
  4177. a1724 4
  4178.     foreach $i (@@modules) {
  4179.     &Chdir($i) && return 1; 
  4180.     $status = &Cvs($i, $command);
  4181.     &Chdir($pwd) && return 1; 
  4182. d1816 4
  4183. a1819 3
  4184.     while(<READ>) {
  4185.     next if (/^#/ && $ignoreComments);
  4186.     push(@@contents, $_);
  4187. a1841 1
  4188.     local($arg);
  4189. d1844 1
  4190. a1844 3
  4191.     foreach $arg (@@_) {
  4192.     print WRITE $arg;
  4193.     }
  4194. d1974 3
  4195. a1976 2
  4196. } elsif (($command eq "status") || ($command eq "diff") || 
  4197.      ($command eq "log")) {
  4198. d1979 1
  4199. a1979 2
  4200.     local($args) = join(' ', @@ARGV);
  4201.     system("cvs -d $cvsroot $command $args");
  4202. @
  4203.  
  4204.  
  4205. 1.6
  4206. log
  4207. @cleaned up a lot of stuff.  Support for individual files.  Links done
  4208. differently. 
  4209. @
  4210. text
  4211. @d148 1
  4212. d153 1
  4213. a153 1
  4214.     if (substr($path, rindex($path, '/') + 1) eq "SCVS") {
  4215. d159 4
  4216. a162 5
  4217.     while(<*>) {
  4218.     printf(STDERR "$_\n") if ($debug);
  4219.     if (-l $_) {
  4220.         $links{$_} = readlink($_);
  4221.     }
  4222. d164 1
  4223. d272 48
  4224. d342 1
  4225. a342 1
  4226.     "f", $OPT_TRUE, *force, "Don't force tags to match.",
  4227. d363 4
  4228. d373 3
  4229. a375 3
  4230.     if ($prune) {
  4231.     $args .= " -p -e SCVS";
  4232.     }
  4233. d379 4
  4234. a382 1
  4235.     print join(' ', @@modules) . "\n";
  4236. d412 1
  4237. d415 6
  4238. d610 1
  4239. a610 1
  4240.     local($args);
  4241. d613 1
  4242. d628 1
  4243. a628 1
  4244.     $args .= " -d";
  4245. d630 1
  4246. a630 1
  4247.     $buffer = "cvs -d $cvsroot update";
  4248. d640 1
  4249. a640 1
  4250.     $tmp = $buffer . " $args" . join(' ', @@names);
  4251. d643 1
  4252. d657 2
  4253. d660 6
  4254. a665 2
  4255.         $args = &ReadFile("SCVS/$argFile", 1);
  4256.         $tmp = $buffer . " $args";
  4257. d672 7
  4258. d753 1
  4259. a753 1
  4260.     local($repos, $pwd, $found);
  4261. d842 1
  4262. a866 1
  4263.     local(@@subdirs) = <*>;
  4264. d870 1
  4265. d872 7
  4266. a878 7
  4267.     printf(STDERR "AllSubdirs on $pwd\n") if ($debug);
  4268.     if ($debug) {
  4269.     foreach $dir (@@subdirs) {
  4270.         printf("\t$dir\n");
  4271.     }
  4272.     }
  4273.     printf("****\n") if ($debug);
  4274. a880 2
  4275.     next if (! -d $dir);
  4276.     next if ($dir eq 'CVS.adm');
  4277. d1340 1
  4278. a1340 1
  4279.     local($head, $tail);
  4280. a1348 1
  4281.     $head = substr($path, 0, rindex($path, '/') - 1);
  4282. @
  4283.  
  4284.  
  4285. 1.5
  4286. log
  4287. @everything seems to work except handling individual files.
  4288. @
  4289. text
  4290. @d1 1
  4291. a1 1
  4292. #! /sprite/cmds/perl 
  4293. d29 2
  4294. a30 1
  4295. $infoFile = "info";
  4296. d59 3
  4297. a61 3
  4298.     local($dir) = $ENV{'PWD'};
  4299.     local($stat, $lastStat);
  4300.     local(@@foo, $tmp);
  4301. d69 1
  4302. a69 1
  4303.     &chdir("..") || die("Can't chdir to .. : $!\n");
  4304. a86 2
  4305.     } elsif (/^objdir:\s+(\S+)\s*$/) {
  4306.         $objdir = $1;
  4307. d94 1
  4308. a94 1
  4309.     &chdir($dir) || die("Can't chdir back to $dir\n");
  4310. d99 33
  4311. a131 1
  4312. # Pack(recurse, dir1, dir2, ...)
  4313. d133 3
  4314. a135 3
  4315. # Finds all symbolic links in the given directory and puts them in a
  4316. # link file in that directory.  The links are stored in alphabetical
  4317. # order.  If recurse is non-zero, Pack will call itself to recurse on
  4318. d140 1
  4319. a140 1
  4320. # Side effects: Dies if chdir to original directory fails.
  4321. d144 1
  4322. a144 4
  4323.     local($recurse) = shift;
  4324.     local(@@dirs) = @@_;
  4325.     local(@@dirStack);
  4326.     local($status) = 0;
  4327. d147 1
  4328. d149 5
  4329. a153 2
  4330.     if (!defined(@@dirs)) {
  4331.     push(@@dirs, $ENV{'PWD'});
  4332. d155 26
  4333. a180 19
  4334.     while($dir = pop(@@dirs)) {
  4335.     local(%links, @@subdirs);
  4336.     push(@@dirStack, $ENV{'PWD'});
  4337.     if (!&chdir($dir)) {
  4338.         printf("Can't chdir to $dir: $!\n");
  4339.         return 1;
  4340.     }
  4341.     if ($debug) {
  4342.         printf(STDERR "Packing %s\n", $ENV{'PWD'});
  4343.     }
  4344.     $addDir = (-d "SCVS") ? 0 : 1;
  4345.     $addFile = (-f "SCVS/$linkFile") ? 0 : 1;
  4346.     while(<*>) {
  4347.         printf(STDERR "$_\n") if ($debug);
  4348.         if (-l $_) {
  4349.         $links{$_} = readlink($_);
  4350.         } elsif (-d $_ && ($_ ne 'CVS.adm')) {
  4351.         push(@@subdirs, $_);
  4352.         }
  4353. d182 2
  4354. a183 1
  4355.     if (defined(%links) || (!$addFile)) {
  4356. d185 1
  4357. a185 30
  4358.         if (!mkdir("SCVS", 0770)) {
  4359.             printf("Couldn't mkdir SCVS: $!\n");
  4360.             return 1;
  4361.         }
  4362.         }
  4363.         if (open(PACK, ">SCVS/$linkFile") == 0) {
  4364.         printf("Can't open $linkFile: $!\n");
  4365.         $status = 1;
  4366.         last;
  4367.         }
  4368.         printf(PACK 
  4369.         "# This file is used by scvs and contains symbolic link\n");
  4370.         printf(PACK 
  4371.         "# information.  Each line is of the form \"link target\"\n");
  4372.         printf(PACK "# \$Header\n");
  4373.         foreach $link (sort keys %links) {
  4374.         printf(PACK "%-24s %s\n", $link, $links{$link});
  4375.         }
  4376.         close(PACK);
  4377.         if ($addFile && (-e "CVS.adm")) {
  4378.         if ($addDir) {
  4379.             system("cvs -d $cvsroot add SCVS");
  4380.         }
  4381.         system("cvs -d $cvsroot add -m\"scvs links\" SCVS/$linkFile");
  4382.         }
  4383.     } 
  4384.     if ($recurse && defined($subdirs[0])) {
  4385.         $status = &Pack($recurse, @@subdirs);
  4386.         if ($status != 0) {
  4387.         last;
  4388. d187 1
  4389. d189 6
  4390. a194 12
  4391.     $dir = pop(@@dirStack);
  4392.     if (!defined($dir)) {
  4393.         die("Internal error: Dir stack screwup in Pack\n");
  4394.     }
  4395.     printf(STDERR "Chdir back to $dir\n") if ($debug);
  4396.     &chdir($dir) || die("Can't chdir back to $dir\n");
  4397.     }
  4398.     if (defined($dirStack[0])) {
  4399.     &chdir($dirStack[0]) || die("Can't chdir back to $dirStack[0]\n");
  4400.     }
  4401.     return $status;
  4402. }
  4403. d197 1
  4404. a197 1
  4405. # Unpack(recurse, dir1, dir2, ...)
  4406. d199 1
  4407. a199 1
  4408. # Reads the link file in the given directory and creates symbolic links
  4409. d205 1
  4410. a205 1
  4411. # Side effects: Dies if chdir to original directory fails.
  4412. d208 1
  4413. a208 3
  4414.     local($recurse) = shift;
  4415.     local(@@dirs) = @@_;
  4416.     local(@@dirStack);
  4417. d211 13
  4418. a223 31
  4419.     if (!defined(@@dirs)) {
  4420.     push(@@dirs, $ENV{'PWD'});
  4421.     }
  4422.     while ($dir = pop(@@dirs)){
  4423.     local(%links, @@subdirs);
  4424.     push(@@dirStack, $ENV{'PWD'});
  4425.     if (!&chdir($dir)) {
  4426.         printf("Chdir to $dir failed: $!\n");
  4427.         return 1;
  4428.     }
  4429.     if ($debug) {
  4430.         printf(STDERR "Unpacking %s\n", $ENV{'PWD'});
  4431.     }
  4432.     if (open(UNPACK, "SCVS/$linkFile")) {
  4433.         while(<UNPACK>) {
  4434.         next if (/^#/);
  4435.         if (/(\S+)\s+(\S+)/) {
  4436.             $link = $1;
  4437.             $value = $2;
  4438.             if (-l $link) {
  4439.             $old = readlink($link);
  4440.             if ($old ne $value) {
  4441.                 printf(
  4442.                 "Changing $link -> $value, instead of -> $old\n");
  4443.                 unlink($link);
  4444.             } else {
  4445.                 next;
  4446.             }
  4447.             } elsif (-e $link) {
  4448.             printf("File $link already exists.\n");
  4449.             $fatal++;
  4450. a224 2
  4451.             } elsif ($verbose) {
  4452.             printf("Creating: $link -> $value\n");
  4453. d226 10
  4454. a235 4
  4455.             if (symlink($value, $link) == 0) { 
  4456.             printf("Can't create link from $link to $value: $!");
  4457.             $fatal++;
  4458.             }
  4459. a237 1
  4460.         close(UNPACK);
  4461. d239 4
  4462. a242 18
  4463.     if ($recurse) {
  4464.         while(<*>) {
  4465.         if (-d $_ && ($_ ne 'CVS.adm')) {
  4466.             push(@@subdirs, $_);
  4467.         }
  4468.         }
  4469.         if (defined($subdirs[0])) {
  4470.         $status = &Unpack($recurse, @@subdirs);
  4471.         if ($status != 0) {
  4472.             last;
  4473.         }
  4474.         }
  4475.     }
  4476.     $dir = pop(@@dirStack);
  4477.     &chdir($dir) || die("Chdir back to$dir failed: $!\n");
  4478.     }
  4479.     if (defined($dirStack[0])) {
  4480.     &chdir($dirStack[0]) || die("Chdir back to $dirStack[0] failed: $!\n");
  4481. d259 2
  4482. a260 4
  4483.     if (!open(REP, "$_[0]/CVS.adm/Repository")) {
  4484.     printf("Open of $_[0]/CVS.adm/Repository failed: $!\n");
  4485.     return ();
  4486.     }
  4487. d263 1
  4488. a263 1
  4489.     return ();
  4490. d271 1
  4491. a271 1
  4492. # Checkout(@@ARGV)
  4493. d274 2
  4494. a275 3
  4495. # Unpack is used to unpack symbolic links.  If the current version
  4496. # of the module is being checked out then the object files are copied from
  4497. # the installed directory. The current user name is added to the SCVS.users
  4498. d277 1
  4499. a277 1
  4500. # printed.  Any options passed to "cvs co" are stored in the SCVS.info
  4501. d282 1
  4502. a282 1
  4503. # Side effects: 
  4504. d286 3
  4505. a288 7
  4506.     local(@@argv) = @@_;
  4507.     local($buffer, $i, @@args, $repos, $me, $date, %count, %dates);
  4508.     local($found, $name, @@modules);
  4509.     #
  4510.     # The code to get object files isn't working yet.
  4511.     #
  4512.     local($getobjs) = 0; 
  4513. d290 1
  4514. a294 1
  4515.     "O", $OPT_FALSE, *getobjs, "Don't get object files."
  4516. d296 2
  4517. a297 1
  4518.     &Opt_Parse(*argv, @@options, $OPT_OPTIONS_FIRST);
  4519. d305 6
  4520. a310 7
  4521.     while ($i = shift(@@argv)) {
  4522.     if ($i !~ /^-/) {
  4523.         unshift(@@argv, $i);
  4524.         last;
  4525.     } elsif (($i eq "-r") || ($i eq "-D")) {
  4526.         push(@@args, $i);
  4527.         $i = shift(@@argv);
  4528. d312 1
  4529. d314 1
  4530. a314 1
  4531.     push(@@args, $i);
  4532. d316 1
  4533. a316 4
  4534.     if (defined(@@args)) {
  4535.     $buffer .= " " . join(' ', @@args);
  4536.     $getobjs = 0;
  4537.     }
  4538. d318 1
  4539. a318 1
  4540.     push(@@args, "-f");
  4541. d321 1
  4542. a321 1
  4543.     push(@@args, "-p");
  4544. d323 2
  4545. a324 4
  4546.  
  4547.     @@modules = @@argv;
  4548.  
  4549.     $me = getlogin;
  4550. d326 1
  4551. d332 1
  4552. d342 1
  4553. a342 2
  4554.         printf("Mkdir of $i/SCVS failed: $!\n");
  4555.         $status = 1;
  4556. d346 2
  4557. a347 3
  4558.     if (!open(CO, ">$i/SCVS/$infoFile")) {
  4559.         printf("Can't open $i/SCVS/$infoFile: $!\n");
  4560.         $status = 1;
  4561. d352 1
  4562. a352 1
  4563.     printf(CO "%s\n", join(' ', @@args));
  4564. d355 1
  4565. d357 2
  4566. a358 22
  4567.     
  4568.     if (&Unpack($recurse, $i)) {
  4569.         printf(STDERR "Unpack failed\n");
  4570.         return 1;
  4571.     }
  4572.     #
  4573.     # Copy the object files if we are checking out the most recent
  4574.     # version of the module.
  4575.     #
  4576.     if ($getobjs && $objdir) {
  4577.         local($pwd) = $ENV{'PWD'};
  4578.         if (!&chdir($i)) {
  4579.         printf("Can't chdir to $i: $!\n");
  4580.         } else {
  4581.         undef(%sources);
  4582.         $status = &GetObjs($i);
  4583.         if ($status) {
  4584.             printf("Can't get object files for module $i.\n");
  4585.         }
  4586.         &chdir($pwd) || die("Can't chdir to $pwd: $!\n");
  4587.         }
  4588.     }
  4589. d366 2
  4590. a367 4
  4591.     if (!open(CO2, ">$repos/$tmpfile")) {
  4592.         printf("Can't open $repos/$tmpfile: $!\n");
  4593.         return 1;
  4594.     }
  4595. d370 2
  4596. a371 4
  4597.         if (!open(CO1, "$repos/$userFile")) {
  4598.         printf("Can't open $repos/$userFile: $!\n");
  4599.         return 1;
  4600.         }
  4601. d375 1
  4602. a375 1
  4603.         if (/^$me\s+([\w\/\.]+)\s+(.*)/) {
  4604. d399 1
  4605. a399 1
  4606.     printf(CO2 "$me $pwd/$i %s", &ctime(time));
  4607. d417 1
  4608. a417 119
  4609. # GetObjs(path)
  4610. #
  4611. # Copy object files from the object directory into the current directory,
  4612. # and do the same for each subdirectory.
  4613. #
  4614. # Results: 0 if successful, 1 otherwise
  4615. #
  4616. # Side effects: 
  4617. #
  4618.  
  4619. sub GetObjs {
  4620.     local($path) = shift;
  4621.     local($pwd) = $ENV{'PWD'};
  4622.     local($status) = 0;
  4623.     local($files, @@files);
  4624.     local($i, $len, $source, $pat);
  4625.     local($quiet) = $verbose ? " " : "-q";
  4626.     local($md) = ($path =~ /.*\.md/) ? 1 : 0;
  4627.  
  4628.     printf(STDERR "GetObjs on $pwd\n") if ($debug);
  4629.     printf(STDERR "Path: $path\n") if ($debug);
  4630.     @@files = <*.c>;
  4631.  
  4632.     #
  4633.     # Get RCS version numbers from the .c files and store them in
  4634.     # the %sources array.
  4635.     #
  4636.     foreach $i (@@files) {
  4637.     printf("Source: $i\n");
  4638.     if (!open(GET, "strings $i |")) {
  4639.         printf("Can't get strings from $i: $!\n");
  4640.         return 1;
  4641.     }
  4642.     $pat = "$i";
  4643.     $pat =~ s/\./\\\./g;
  4644.     $pat = "\\Header: $pat\\S+)\\s+(\\d+\\.\\d+)";
  4645.     study($pat);
  4646.     while(<GET>) {
  4647.         if (m|$pat|) {
  4648.         if ($md) {
  4649.             $sources{"$i:MD"} = "$2";
  4650.         } else {
  4651.             $sources{"$i"} = "$2";
  4652.         }
  4653.         last;
  4654.         }
  4655.     }
  4656.     close(GET);
  4657.     }
  4658.     #
  4659.     # Now get the RCS version numbers from the .o files and compare
  4660.     # them with the corresponding .c files.  If they are the same we
  4661.     # copy the object file to the current directory.
  4662.     #
  4663.     if (-d "$objdir/$path") {
  4664.     local($tag, $found);
  4665.     @@files = <$objdir/$path/*.o>;
  4666.     foreach $i (@@files) {
  4667.         printf("Object: $i\n");
  4668.         system("update -t $quiet $i .");
  4669.         if ($?) {
  4670.         printf("Update failed: $?\n");
  4671.         return 1;
  4672.         }
  4673.         $i = substr($i, rindex($i, '/') + 1);
  4674.         printf("Opening $i\n");
  4675.         if (!open(GET, "strings $i |")) {
  4676.         printf("Can't get strings from $i: $!\n");
  4677.         return 1;
  4678.         }
  4679.         $pat = $i;
  4680.         $pat =~ s/\.o/\\\.c/;
  4681.         $pat = "\\Header: $pat\\S+)\\s+(\\d+\\.\\d+)";
  4682.         study($pat);
  4683.         printf("i = $i\n");
  4684.         $found = 0;
  4685.         while(<GET>) {
  4686.         if (m|$pat|) {
  4687.             local($version) = $2;
  4688.             local($file) = $i;
  4689.             $file =~ s/\.o/\.c/;
  4690.             if ($md) {
  4691.             $tag = "$file:MD";
  4692.             if (defined($sources{"$tag"})) {
  4693.                 $found = 1;
  4694.                 last;
  4695.             }
  4696.             }
  4697.             if (defined($sources{"$file"})) {
  4698.             $tag = $file;
  4699.             $found = 1;
  4700.             } else {
  4701.             printf("Warning: No source file for $i\n");
  4702.             }
  4703.             last;
  4704.         }
  4705.         }
  4706.         if ($found) {
  4707.         printf("Found $tag\n");
  4708.         if ($sources{"$tag"} ne "$version") {
  4709.             printf(
  4710.         "Object file $i has different version, %s != %s\n",
  4711.             $version, $sources{"$tag"});
  4712.             unlink("$i");
  4713.         }
  4714.         } else {
  4715.         unlink("$i");
  4716.         }
  4717.         close(GET);
  4718.     }
  4719.     }
  4720.     $status = &AllSubdirs($path, "GetObjs");
  4721.     return $status;
  4722. }
  4723.  
  4724.  
  4725.  
  4726. #
  4727. # Unlock(@@modules)
  4728. d427 1
  4729. a427 1
  4730. sub Unlock {
  4731. d429 2
  4732. a430 1
  4733.     local($cvsdir, $i, $lock, $status); 
  4734. d432 7
  4735. d440 6
  4736. a445 4
  4737.     if (! -d "$i") {
  4738.         printf(STDERR "Directory $i does not exist\n");
  4739.         $status = 1;
  4740.         next;
  4741. d447 2
  4742. a448 2
  4743.     if (! -f "$i/CVS.adm/Repository") {
  4744.         printf(STDERR "Directory $i not checked out.\n");
  4745. d450 1
  4746. a450 1
  4747.         next;
  4748. d452 1
  4749. a452 2
  4750.     $cvsdir = $cvsroot . "/" . `cat $i/CVS.adm/Repository`;
  4751.     chop($cvsdir);
  4752. d455 2
  4753. a456 4
  4754.         if (!unlink($lock)) {
  4755.         printf("Can't remove $lock: $!\n");
  4756.         $status = 1;
  4757.         }
  4758. d463 1
  4759. a463 1
  4760. # LockModules(username, @@modules)
  4761. d473 1
  4762. a473 2
  4763. sub LockModules {
  4764.     local($me) = shift;
  4765. d479 2
  4766. d482 7
  4767. d490 6
  4768. a495 4
  4769.     if (! -d "$i") {
  4770.         printf(STDERR "Directory $i does not exist\n");
  4771.         $status = 1;
  4772.         last;
  4773. d497 2
  4774. a498 2
  4775.     if (! -f "$i/CVS.adm/Repository") {
  4776.         printf(STDERR "Directory $i not checked out.\n");
  4777. d500 1
  4778. a500 1
  4779.         last;
  4780. d502 8
  4781. a509 8
  4782.     $cvsdir = $cvsroot . "/" . `cat $i/CVS.adm/Repository`;
  4783.     chop($cvsdir);
  4784.     if (open(LM, "$cvsdir/LOCK.scvs")) {
  4785.         $name = <LM>;
  4786.         close(LM);
  4787.         printf(STDERR "Module $i is already locked by $name\n");
  4788.         $status = 1;
  4789.         last;
  4790. d511 4
  4791. a514 9
  4792.     open(LM, ">$cvsdir/LOCK.scvs") || 
  4793.         die("Can't open $cvsdir/LOCK.scvs: $!\n");
  4794.     printf(LM "$me\n");
  4795.     close(LM);
  4796.     push(@@mylocks, "$cvsdir/LOCK.scvs");
  4797.     }
  4798.     if ($status) {
  4799.     if (&Unlock(@@mylocks)) {
  4800.         die("Internal error: Can't clean up in LockModules\n");
  4801. d516 10
  4802. a525 4
  4803.     } else {
  4804.     push(@@locks, @@mylocks);
  4805.     }
  4806.     return $status;
  4807. d529 1
  4808. a529 1
  4809. # Update(@@modules)
  4810. d535 1
  4811. a535 1
  4812. # for update are retrieved from the SCVS.info file.
  4813. d542 3
  4814. a544 3
  4815. sub Update {
  4816.     local(@@modules) = @@_;
  4817.     local($buffer, $i, $cvsdir, $me, $date, %count, %dates);
  4818. a545 2
  4819.     local($useOld) = 1;
  4820.     local($type) = 0;
  4821. d548 6
  4822. d557 2
  4823. a558 5
  4824.     while ($i = shift(@@modules)) {
  4825.     if ($i !~ /^-/) {
  4826.         unshift(@@modules, $i);
  4827.         last;
  4828.     }
  4829. d561 1
  4830. a561 1
  4831.     $buffer = "cvs -d $cvsroot update";
  4832. d563 2
  4833. a564 2
  4834.     if ($#modules < $[) {
  4835.     push(@@modules, ".");
  4836. d566 1
  4837. a566 1
  4838.     # Make sure all the modules are unlocked, then lock them.
  4839. d568 2
  4840. a569 4
  4841.     $me = getlogin;
  4842.     $status = &LockModules($me, @@modules); 
  4843.     if ($status) {
  4844.     return $status;
  4845. d571 17
  4846. a587 6
  4847.     $dir = $ENV{'PWD'};
  4848.     foreach $i (@@modules) {
  4849.     local($tmp);
  4850.     if (!&chdir($i)) {
  4851.         printf("Can't chdir to $i: $!\n");
  4852.         return 1;
  4853. d589 11
  4854. a599 5
  4855.     if (open(UP, "SCVS/$infoFile")) {
  4856.         while(<UP>) {
  4857.         next if (/^\#/);
  4858.         $args .= " $_";
  4859.         last;
  4860. d601 1
  4861. a602 12
  4862.     close(UP);
  4863.     $tmp = $buffer . " $args" . join(' ', @@files);
  4864.     printf("$tmp\n") if ($debug);
  4865.     system($tmp);
  4866.     &chdir($dir) || die("Can't chdir to $dir: $!\n");
  4867.     }
  4868.  
  4869.     # Unpack each of the modules.
  4870.  
  4871.     if (&Unpack(1, @@modules)) {
  4872.     printf("Unpack failed\n");
  4873.     return 1;
  4874. d608 1
  4875. a608 1
  4876. # Changed($path, *modified)
  4877. d614 1
  4878. a614 1
  4879. # Results: 0 if successful, 1 otherwise
  4880. d620 1
  4881. a620 1
  4882.     local(*modified) = shift;
  4883. d625 2
  4884. a626 4
  4885.     if (!open(CHG, "cvs -d $cvsroot info |")) {
  4886.     printf("Can't do cvs info on $path: $!\n");
  4887.     return 1;
  4888.     }
  4889. d640 15
  4890. a654 2
  4891.     $status = &AllSubdirs($path, "Changed", *modified);
  4892.     return $status;
  4893. d658 1
  4894. a658 1
  4895. # Done(@@modules)
  4896. d669 1
  4897. a669 1
  4898. sub Done {
  4899. d674 1
  4900. a674 1
  4901.     local($dir) = $ENV{'PWD'};
  4902. d685 1
  4903. a685 2
  4904.     printf("Done command requires a list of modules\n");
  4905.     return 1;
  4906. d688 1
  4907. a688 1
  4908.     $status = &LockModules($me, @@modules); 
  4909. d695 1
  4910. a695 1
  4911.     if (! -e $i) {
  4912. d699 5
  4913. a703 3
  4914.     if (!&chdir($i)) {
  4915.         printf("Can't chdir to $i: $!\n");
  4916.         return 1;
  4917. a704 2
  4918.     $modified = 0;
  4919.     $status = &Changed($i, *modified);
  4920. d735 1
  4921. a735 1
  4922.         if ($1 eq "$dir/$i") {
  4923. d756 1
  4924. a756 4
  4925.     if (!&chdir($dir)) {
  4926.         printf("Can't chdir to $dir: $!\n");
  4927.         return 1;
  4928.     }
  4929. d790 2
  4930. d804 16
  4931. a819 11
  4932.     if (!&chdir($dir)) {
  4933.         printf("Can't chdir to $dir: $!\n");
  4934.         return 1;
  4935.     }
  4936.     if ($substatus = &$routine($path . "/$dir", @@_)) {
  4937.         $status = $substatus;
  4938.     }
  4939.     &chdir($pwd) || die("Can't chdir to $pwd: $!\n");
  4940.     }
  4941.     return $status;
  4942. }
  4943. d823 1
  4944. a823 1
  4945. # VerifyCurrent($path)
  4946. d828 1
  4947. a828 1
  4948. # Results: 0 if successful, 1 otherwise
  4949. d846 2
  4950. a847 4
  4951.     if (!open(CHK, "cvs -d $cvsroot info |")) {
  4952.     printf("Can't get info for $path: $!\n");
  4953.     return 1;
  4954.     }
  4955. d878 1
  4956. a878 1
  4957. # CommitDir
  4958. d880 1
  4959. d886 1
  4960. a886 1
  4961. sub CommitDir {
  4962. d906 2
  4963. a907 4
  4964.         if (!open(CMTDIR2, ">$tmpfile")) {
  4965.         printf("Can't open $path/$tmpfile: $!\n");
  4966.         return 1;
  4967.         }
  4968. d927 1
  4969. a927 1
  4970. # CommitModules(@@modules)
  4971. d929 1
  4972. a929 1
  4973. # Commit any changes to the modules. 
  4974. d940 3
  4975. a942 3
  4976. sub CommitModules {
  4977.     local(@@modules) = @@_;
  4978.     local($dir, $i);
  4979. d947 2
  4980. d951 9
  4981. a959 5
  4982.     &Opt_Parse(*modules, @@options, 0);
  4983.     while ($i = shift(@@modules)) {
  4984.     if ($i !~ /^-/) {
  4985.         unshift(@@modules, $i);
  4986.         last;
  4987. d961 1
  4988. a961 1
  4989.     push(@@args, $i);
  4990. d963 3
  4991. a965 2
  4992.     if ($#modules < $[) {
  4993.     push(@@modules, ".");
  4994. a966 1
  4995.     $args = join(' ', @@args);
  4996. d968 11
  4997. a978 5
  4998.     # Make sure all the modules exist.
  4999.     foreach $i (@@modules) {
  5000.     if (! -d $i) {
  5001.         printf("Directory $i does not exist\n");
  5002.         return 1;
  5003. d980 1
  5004. a980 2
  5005.     }
  5006.     # Make sure all the modules are unlocked, then lock them.
  5007. d982 11
  5008. a992 34
  5009.     $status = &LockModules(getlogin, @@modules); 
  5010.     if ($status) {
  5011.     return $status;
  5012.     }
  5013.     $dir = $ENV{'PWD'};
  5014.  
  5015.     #
  5016.     # All the modules and their subdirectories must be up-to-date.
  5017.     #
  5018.     foreach $i (@@modules) {
  5019.     if (!&chdir($i)) {
  5020.         printf("Can't chdir to $i: $!\n");
  5021.         return 1;
  5022.     }
  5023.     $path = $i;
  5024.     $status = &VerifyCurrent($path, *stale, *modified);
  5025.     if ($status) {
  5026.         return $status;
  5027.     }
  5028.     &chdir($dir) || die("Can't chdir to $dir: $!\n");
  5029.     }
  5030.  
  5031.     if ($#stale >= $[) {
  5032.     printf("Update your sources using \"scvs update\".\n");
  5033.     return $status;
  5034.     }
  5035.  
  5036.     #
  5037.     # Commit all directories that were modified.
  5038.     #
  5039.     foreach $i (@@modified) {
  5040.     if (!&chdir($i)) {
  5041.         printf("Can't chdir to $i: $!\n");
  5042.         return 1;
  5043. d994 4
  5044. a997 4
  5045.     $path = $i;
  5046.     $status = &CommitDir($path, $args);
  5047.     if ($status) {
  5048.         last;
  5049. d999 13
  5050. a1011 4
  5051.     &chdir($dir) || die("Can't chdir to $dir: $!\n");
  5052.     }
  5053.     return $status;
  5054. }
  5055. d1015 1
  5056. a1015 1
  5057. # Who(@@modules)
  5058. d1024 1
  5059. a1024 1
  5060. sub Who {
  5061. d1026 1
  5062. a1026 1
  5063.     local($dir, $i);
  5064. d1028 1
  5065. a1028 1
  5066.     local($path, $repos);
  5067. d1030 3
  5068. d1036 1
  5069. a1036 10
  5070.     # Make sure all the modules exist.
  5071.     foreach $i (@@modules) {
  5072.     if (! -d $i) {
  5073.         printf("Directory $i does not exist\n");
  5074.         return 1;
  5075.     }
  5076.     }
  5077.     # Make sure all the modules are unlocked, then lock them.
  5078.  
  5079.     $status = &LockModules(getlogin, @@modules); 
  5080. d1040 1
  5081. a1040 1
  5082.     $dir = $ENV{'PWD'};
  5083. a1041 3
  5084.     #
  5085.     # All the modules and their subdirectories must be up-to-date.
  5086.     #
  5087. d1044 5
  5088. a1048 10
  5089.     $repos = &Repository($i);
  5090.     next module if (!defined($repos));
  5091.     if (!open(WHO, "$repos/$userFile")) {
  5092.         printf("Module $i is not checked out\n");
  5093.         next module;
  5094.     }
  5095.     while (<WHO>) {
  5096.         next if (/^#/);
  5097.         if (/^(\S+)\s+([\w\/\.]+)\s+(.*)/) {
  5098.         $users{$1} = $3;
  5099. d1051 4
  5100. a1054 3
  5101.     close(WHO);
  5102.     foreach $i (keys %users) {
  5103.         printf("$i\n");
  5104. d1056 11
  5105. a1066 2
  5106.     }
  5107.     return $status;
  5108. d1070 1
  5109. a1070 1
  5110. # Add(@@names)
  5111. d1079 1
  5112. a1079 1
  5113. sub Add {
  5114. d1084 2
  5115. a1085 1
  5116.     local($dir);
  5117. d1088 1
  5118. a1088 2
  5119.     printf(STDERR "Add command requires list of files\n");
  5120.     return 1;
  5121. d1090 1
  5122. a1090 1
  5123.     $status = &LockModules(getlogin, "."); 
  5124. d1094 4
  5125. a1097 1
  5126.  
  5127. d1121 4
  5128. a1124 20
  5129.         } else {
  5130.         if (! -d "SCVS") {
  5131.             printf("Creating SCVS directory\n") if ($debug);
  5132.             if (!mkdir("SCVS", 0770)) {
  5133.             printf("Couldn't mkdir SCVS: $!\n");
  5134.             return 1;
  5135.             }
  5136.             printf("Adding SCVS directory\n") if ($debug);
  5137.             system("cvs -d $cvsroot add SCVS");
  5138.         }
  5139.         if (! -d "SCVS/CVS.adm") {
  5140.             printf("Adding SCVS directory\n") if ($debug);
  5141.             system("cvs -d $cvsroot add SCVS");
  5142.         }
  5143.         if (! -f "SCVS/$linkFile") {
  5144.             if (!open(ADD, ">SCVS/$linkFile")) {
  5145.             printf(STDERR "Can't open SCVS/$linkFile: $!\n");
  5146.             return 1;
  5147.             }
  5148.             printf(ADD 
  5149. d1126 1
  5150. a1126 1
  5151.             printf(ADD 
  5152. d1128 8
  5153. a1135 15
  5154.             printf(ADD "# \$Header\n");
  5155.             close(ADD);
  5156.             $dir = $ENV{'PWD'};
  5157.             if (!chdir("SCVS")) {
  5158.             printf("Chdir to SCVS failed: $!\n");
  5159.             return 1;
  5160.             }
  5161.             printf("Adding $linkFile directory\n") if ($debug);
  5162.             system("cvs -d $cvsroot add -m \"sym links\" $linkFile");
  5163.             if (!chdir("$dir")) {
  5164.             printf("Chdir to $dir failed: $!\n");
  5165.             return 1;
  5166.             }
  5167.  
  5168.         }
  5169. d1140 17
  5170. d1159 2
  5171. a1160 4
  5172.         if (!open(ADD, ">>SCVS/$linkFile")) {
  5173.         printf(STDERR "Can't open SCVS/$linkFile: $!\n");
  5174.         return 1;
  5175.         }
  5176. d1171 1
  5177. a1171 1
  5178. # Remove(@@names)
  5179. d1180 1
  5180. a1180 1
  5181. sub Remove {
  5182. d1186 1
  5183. a1186 2
  5184.     printf(STDERR "Remove command requires list of files\n");
  5185.     return 1;
  5186. d1188 1
  5187. a1188 1
  5188.     $status = &LockModules(getlogin, "."); 
  5189. d1217 1
  5190. a1217 1
  5191.     if (defined(@@delete)) {
  5192. d1252 1
  5193. a1252 1
  5194. # InfoDir($path)
  5195. d1261 1
  5196. a1261 1
  5197. sub InfoDir {
  5198. a1270 1
  5199.     printf("Info on $path\n") if ($debug);
  5200. d1274 2
  5201. a1275 4
  5202.     if (!open(INFO, "cvs -d $cvsroot info |")) {
  5203.         printf("Can't do cvs info on $path: $!\n");
  5204.         return 1;
  5205.     }
  5206. d1288 2
  5207. a1289 4
  5208.         if (!open(INFO, "cvs -d $cvsroot diff $linkFile |")) {
  5209.         printf("Can't do cvs diff on $path/$linkFile: $!\n");
  5210.         return 1;
  5211.         }
  5212. d1308 2
  5213. a1309 4
  5214.         if (!open(INFO, "$linkFile")) {
  5215.         printf("Can't open $linkFile: $!\n");
  5216.         return 1;
  5217.         }
  5218. d1321 1
  5219. d1325 1
  5220. a1325 1
  5221.     $status = &AllSubdirs($path, "InfoDir");
  5222. d1330 1
  5223. a1330 1
  5224. # Info(@@modules)
  5225. d1339 1
  5226. a1339 1
  5227. sub Info {
  5228. d1341 1
  5229. a1341 1
  5230.     local($dir, $i);
  5231. a1343 1
  5232.     local($path);
  5233. d1347 2
  5234. d1352 1
  5235. a1352 10
  5236.     # Make sure all the modules exist.
  5237.     foreach $i (@@modules) {
  5238.     if (! -d $i) {
  5239.         printf("Directory $i does not exist\n");
  5240.         return 1;
  5241.     }
  5242.     }
  5243.     # Make sure all the modules are unlocked, then lock them.
  5244.  
  5245.     $status = &LockModules(getlogin, @@modules); 
  5246. d1356 1
  5247. a1356 1
  5248.     $dir = $ENV{'PWD'};
  5249. d1359 3
  5250. a1361 6
  5251.     if (!&chdir($i)) {
  5252.         printf("Can't chdir to $i: $!\n");
  5253.         return 1;
  5254.     }
  5255.     $path = $i;
  5256.     $status = &InfoDir($path);
  5257. d1365 1
  5258. a1365 1
  5259.     &chdir($dir) || die("Can't chdir to $dir: $!\n");
  5260. d1367 1
  5261. d1371 1
  5262. a1371 1
  5263. # CvsCmdDir($path, $command)
  5264. d1381 1
  5265. a1381 1
  5266. sub CvsCmdDir {
  5267. d1398 1
  5268. a1398 1
  5269.     $status = &AllSubdirs($path, "CvsCmdDir", $command);
  5270. d1418 1
  5271. a1418 1
  5272.     local($dir, $i, @@args);
  5273. d1422 1
  5274. d1426 7
  5275. a1435 16
  5276.     while ($i = shift(@@modules)) {
  5277.     if ($i !~ /^-/) {
  5278.         unshift(@@modules, $i);
  5279.         last;
  5280.     }
  5281.     push(@@args, $i);
  5282.     }
  5283.  
  5284.     # Make sure all the modules exist.
  5285.     foreach $i (@@modules) {
  5286.     if (! -d $i) {
  5287.         printf("Directory $i does not exist\n");
  5288.         return 1;
  5289.     }
  5290.     }
  5291.     # Make sure all the modules are unlocked, then lock them.
  5292. d1437 1
  5293. a1437 1
  5294.     $status = &LockModules(getlogin, @@modules); 
  5295. a1440 1
  5296.     $dir = $ENV{'PWD'};
  5297. d1442 1
  5298. d1444 3
  5299. a1446 7
  5300.     if (!&chdir($i)) {
  5301.         printf("Can't chdir to $i: $!\n");
  5302.         return 1;
  5303.     }
  5304.     $path = $i;
  5305.     $status = &CvsCmdDir($path, $command);
  5306.     &chdir($dir) || die("Can't chdir to $dir: $!\n");
  5307. d1452 10
  5308. d1468 10
  5309. d1480 15
  5310. d1500 68
  5311. a1567 1
  5312.     printf("\t$i\n");
  5313. d1569 2
  5314. d1575 80
  5315. a1659 1
  5316. $fatal = 0;
  5317. d1661 1
  5318. d1670 1
  5319. a1670 1
  5320. printf("$command\n") if ($debug);
  5321. d1672 1
  5322. a1672 5
  5323. if ($command eq "pack") {
  5324.     local(@@options) = ("l", $OPT_FALSE, *recurse, "Recurse on subdirectories");
  5325.     &Opt_Parse(*ARGV, @@options, 0);
  5326.     $status = &Pack($recurse, @@ARGV);
  5327. } elsif ($command eq "unpack") {
  5328. d1675 1
  5329. a1675 1
  5330.     $status = &Unpack($recurse, @@ARGV);
  5331. d1680 1
  5332. a1680 1
  5333.     $status = &Unlock(@@ARGV);
  5334. d1682 1
  5335. a1682 1
  5336.     $status = &LockModules(getlogin, @@ARGV);
  5337. d1685 1
  5338. a1685 1
  5339.     $status = &Update(@@ARGV);
  5340. d1687 1
  5341. a1687 1
  5342.     $status = &Done(@@ARGV);
  5343. d1689 1
  5344. a1689 1
  5345.     $status = &CommitModules(@@ARGV);
  5346. d1691 1
  5347. a1691 1
  5348.     $status = &Who(@@ARGV);
  5349. d1693 1
  5350. a1693 1
  5351.     $status = &Add(@@ARGV);
  5352. d1695 1
  5353. a1695 1
  5354.     $status = &Remove(@@ARGV);
  5355. d1697 1
  5356. a1697 1
  5357.     $status = &Info(@@ARGV);
  5358. d1704 1
  5359. @
  5360.  
  5361.  
  5362. 1.4
  5363. log
  5364. @prior to change to use cvs info for instead of status and diff
  5365. @
  5366. text
  5367. @d44 1
  5368. a44 1
  5369. @@cvsCmds = ("add", "remove", "join", "patch", "tag");
  5370. a97 1
  5371.  
  5372. a188 1
  5373.  
  5374. d321 1
  5375. a321 1
  5376.     local($force, $prune) = (1, 1);
  5377. d324 1
  5378. a324 1
  5379.     "F", $OPT_FALSE, *force, "Don't force tags to match.",
  5380. d340 4
  5381. d511 1
  5382. a511 1
  5383.     $pat = "\\\$Header: /local/src/cmds/scvs/RCS/scvs,v 1.3 91/09/02 12:53:04 jhh Exp Locker: jhh $pat\\S+)\\s+(\\d+\\.\\d+)";
  5384. d548 1
  5385. a548 1
  5386.         $pat = "\\\$Header: /local/src/cmds/scvs/RCS/scvs,v 1.3 91/09/02 12:53:04 jhh Exp Locker: jhh $pat\\S+)\\s+(\\d+\\.\\d+)";
  5387. d762 1
  5388. a762 1
  5389. # Diff(path)
  5390. d764 14
  5391. a777 45
  5392. # Check to see if any files in the current directory and its subdirectories
  5393. # have been changed.
  5394.  
  5395. # Results: 0 if no files have been changed, 1 otherwise.
  5396. #
  5397. # Side effects: 
  5398. #
  5399. sub Diff {
  5400.     local($path) = shift;
  5401.     local(@@tmp, $file);
  5402.     local($status) = 0;
  5403.  
  5404.     printf("Diffing $path\n") if ($debug);
  5405.     if (! -e "CVS.adm" && ($path !~ m|.*/SCVS|)) {
  5406.     printf("$path is not checked out\n");
  5407.     return 1;
  5408.     }
  5409.     if (!open(DIFF, "cvs -d $cvsroot diff |")) {
  5410.     printf("Can't diff $path: $!\n");
  5411.     return 1;
  5412.     }
  5413.     while(<DIFF>) {
  5414.     if (/^diff/) {
  5415.         @@tmp = split(' ', $_);
  5416.         $file = pop(@@tmp);
  5417.         printf("$path/$file has been changed.\n");
  5418.         $status = 1;
  5419.     }
  5420.     }
  5421.     close(DIFF);
  5422.  
  5423.     if (!open(DIFF, "cvs -d $cvsroot status |")) {
  5424.     printf("Can't get status of $path: $!\n");
  5425.     return 1;
  5426.     }
  5427.     while(<DIFF>) {
  5428.     if (/^File:\s+([\w\.]+)$/) {
  5429.         $file = $1;
  5430.     } elsif (/^From:\s+New\s+file/) {
  5431.         printf("File $path/$file is new.\n");
  5432.         $status = 2;
  5433.     } elsif (/^File:\s+no\s+file\s+(\S+)/) {
  5434.         printf("File $path/$1 has been removed.\n");
  5435.         $status = 2;
  5436.     }
  5437. d779 3
  5438. a781 4
  5439.     close(DIFF);
  5440.  
  5441.     if ($recurse) {
  5442.     $status = &AllSubdirs($path, "Diff");
  5443. d783 14
  5444. a798 3
  5445.  
  5446.  
  5447.  
  5448. d820 1
  5449. d847 3
  5450. a849 2
  5451.     $modified = &Diff($i);
  5452.     if ($modified == 2) {
  5453. d939 6
  5454. d946 1
  5455. d963 1
  5456. a963 1
  5457. # CheckStatus
  5458. d972 1
  5459. a972 1
  5460. sub CheckStatus {
  5461. d974 2
  5462. a977 1
  5463.     local($file, $from, $newfile);
  5464. d979 2
  5465. d982 1
  5466. a982 1
  5467.     printf("Checking status of $path\n") if ($debug);
  5468. d986 2
  5469. a987 2
  5470.     if (!open(CHK, "cvs -d $cvsroot status |")) {
  5471.     printf("Can't get status of $path: $!\n");
  5472. a989 2
  5473.     undef($from);
  5474.     undef($newfile);
  5475. d991 12
  5476. a1002 22
  5477.     if (/^File:\s+([\w\.]+)$/) {
  5478.         $file = $1;
  5479.     } elsif (/^From:\s+(-)?([\d\.]+)/) {
  5480.         if (!defined($1) && defined($newfile)) {
  5481.         printf("New file $path/$newfile has been added.\n");
  5482.         $status = 2;
  5483.         }
  5484.         $from = $2;
  5485.         undef($newfile);
  5486.     } elsif ((/^RCS:.*Attic.*/) && (defined($file))) {
  5487.         printf("File $path/$file has been deleted.\n");
  5488.         $status = 2;
  5489.     } elsif ((/^RCS:\s+([\d\.]+)/) && (defined($from))) {
  5490.         if ($1 ne $from) {
  5491.         printf("File $path/$file is out of date.\n");
  5492.         $status = 2;
  5493.         }
  5494.         undef($from);
  5495.         undef($file);
  5496.     } elsif (/^File:\s+no\s+file\s+(\S+)/) {
  5497.         $newfile = $1;
  5498.     }
  5499. d1005 8
  5500. d1014 1
  5501. a1014 1
  5502.     $status = &AllSubdirs($path, "CheckStatus");
  5503. d1033 1
  5504. d1039 25
  5505. a1063 4
  5506.     $status = &Pack($recurse);
  5507.     if ($status) {
  5508.     printf("Can't pack $pwd.\n");
  5509.     return $status;
  5510. a1064 1
  5511.     printf("$path:\n");
  5512. a1065 3
  5513.     if ($recurse) {
  5514.     $status = &AllSubdirs($path, "CommitDir", $args);
  5515.     }
  5516. d1089 1
  5517. a1123 1
  5518.     local($stale);
  5519. d1129 3
  5520. a1131 3
  5521.     $stale = &CheckStatus($path);
  5522.     if ($stale) {
  5523.         $status = $stale;
  5524. d1136 2
  5525. a1137 4
  5526.     if ($status) {
  5527.     if ($status == 2) {
  5528.         printf("Update your sources using \"scvs update\".\n");
  5529.     }
  5530. d1142 1
  5531. a1142 1
  5532.     # Commit all modules and their subdirectories.
  5533. d1144 1
  5534. a1144 1
  5535.     foreach $i (@@modules) {
  5536. d1154 1
  5537. d1220 323
  5538. d1646 1
  5539. a1646 1
  5540.     foreach $i sort ("pack", "unpack", "checkout", "unlock", "lock", "update", 
  5541. d1696 6
  5542. d1703 1
  5543. a1703 1
  5544.      ($command eq "log") || ($command eq "info")) {
  5545. @
  5546.  
  5547.  
  5548. 1.3
  5549. log
  5550. @*** empty log message ***
  5551. @
  5552. text
  5553. @d7 1
  5554. a7 1
  5555. # $Header: /sprite/lib/forms/RCS/proto.csh,v 1.5 91/02/09 13:24:51 ouster Exp $ SPRITE (Berkeley)
  5556. d44 1
  5557. a44 1
  5558. @@cvsCmds = ("diff", "add", "remove", "join", "patch", "tag", "status", "log");
  5559. d453 1
  5560. a453 1
  5561.         printf("You also have these copies of the $i module:\n");
  5562. d464 1
  5563. a464 1
  5564.         printf("The following users have copies of module $i:\n"); 
  5565. d509 1
  5566. a509 1
  5567.     $pat = "\\\$Header:\\s+(\\S+$pat\\S+)\\s+(\\d+\\.\\d+)";
  5568. d546 1
  5569. a546 1
  5570.         $pat = "\\\$Header:\\s+(\\S+$pat\\S+)\\s+(\\d+\\.\\d+)";
  5571. d607 10
  5572. d650 10
  5573. d701 1
  5574. a701 1
  5575.     local($buffer, $i, @@args, $cvsdir, $me, $date, %count, %dates);
  5576. d706 1
  5577. d710 7
  5578. d739 1
  5579. a739 1
  5580.         $args = $_;
  5581. d774 1
  5582. d931 1
  5583. a931 1
  5584. # AllSubdirs(path, routine)
  5585. d939 2
  5586. d963 1
  5587. a963 1
  5588.     if ($substatus = &$routine($path . "/$dir")) {
  5589. a1015 2
  5590.         undef($from);
  5591.         undef($file);
  5592. d1017 2
  5593. d1040 1
  5594. d1055 1
  5595. a1055 8
  5596.     $output = `cvs -d $cvsroot ci -a 2>&1`;
  5597.     print $output;
  5598.     if ($?) {
  5599.     if ($output ne "cvs: there is nothing to commit!\n") {
  5600.         printf("cvs commit failed: $?\n");
  5601.         return 1;
  5602.     }
  5603.     }
  5604. d1057 1
  5605. a1057 1
  5606.     $status = &AllSubdirs($path, "CommitDir");
  5607. d1085 7
  5608. d1095 2
  5609. d1145 1
  5610. a1145 1
  5611.     $status = &CommitDir($path);
  5612. d1212 93
  5613. d1318 2
  5614. a1319 1
  5615.             "done", "commit", "who", @@cvsCmds) {
  5616. d1367 3
  5617. d1371 1
  5618. a1371 1
  5619.     $args = join(' ', @@ARGV);
  5620. @
  5621.  
  5622.  
  5623. 1.2
  5624. log
  5625. @work in progress on getting GetObjs to work.
  5626. @
  5627. text
  5628. @d44 2
  5629. d144 1
  5630. a144 1
  5631.     if (defined(%links)) {
  5632. d160 1
  5633. a160 1
  5634.         printf(PACK '# $Header\n');
  5635. d171 1
  5636. a171 1
  5637.     }
  5638. d319 4
  5639. a322 1
  5640.     local($getobjs) = 1; 
  5641. d491 1
  5642. d507 1
  5643. a507 1
  5644.     $pat = "$path/$i";
  5645. d513 5
  5646. a517 2
  5647.         $sources{"$path/$i"} = "$2";
  5648.         printf("$path/$i = $2\n");
  5649. d529 1
  5650. d549 1
  5651. d555 5
  5652. a559 8
  5653.             printf("Looking in $path/$file\n");
  5654.             if (defined($sources{"$path/$file"})) {
  5655.             printf("Found $path/$file\n");
  5656.             if ($sources{"$path/$file"} ne "$version") {
  5657.                 printf(
  5658.             "Object file $i has different version, %s != %s\n",
  5659.                 $version, $sources{"$path/$file"});
  5660.                 unlink("$i");
  5661. d561 4
  5662. a564 12
  5663.             } elsif ($path =~ /.*\.md/) {
  5664.             $file = substr($path, rindex($path, '/')+1) . "/$file";
  5665.             printf("Looking in $file\n");
  5666.             if (defined($sources{"$file"})) {
  5667.                 printf("Found $file\n");
  5668.                 if ($sources{"$file"} ne "$version") {
  5669.                 printf(
  5670.             "Object file $i has different version, %s != %s\n",
  5671.                 $version, $sources{"$file"});
  5672.                 unlink("$i");
  5673.                 }
  5674.             }
  5675. d569 8
  5676. a576 1
  5677.         } else {
  5678. d579 2
  5679. d685 1
  5680. a685 1
  5681.     local($module, $current);
  5682. d692 1
  5683. a692 3
  5684.     @@tmp = split('/', $ENV{'PWD'});
  5685.     push(@@modules, pop(@@tmp));
  5686.     $current = 1;
  5687. a693 1
  5688.  
  5689. d701 7
  5690. a707 1
  5691.     if ($current) {
  5692. d716 4
  5693. a719 23
  5694.     $buffer .= " $args";
  5695.     printf("$buffer\n");
  5696.     system($buffer);
  5697.     } else {
  5698.     foreach $i (@@modules) {
  5699.         local($tmp);
  5700.         if (!&chdir($i)) {
  5701.         printf("Can't chdir to $i: $!\n");
  5702.         return 1;
  5703.         }
  5704.         if (open(UP, "SCVS/$infoFile")) {
  5705.         while(<UP>) {
  5706.             next if (/^\#/);
  5707.             $args = $_;
  5708.             last;
  5709.         }
  5710.         }
  5711.         close(UP);
  5712.         $tmp = $buffer . " $args" . join(' ', @@files);
  5713.         printf("$tmp\n");
  5714.         system($tmp);
  5715.         &chdir("..");
  5716.     }
  5717. d724 1
  5718. a724 6
  5719.     if ($current) {
  5720.     if (&Unpack(1)) {
  5721.         printf("Unpack failed\n");
  5722.         return 1;
  5723.     }
  5724.     } elsif (&Unpack(1, @@modules)) {
  5725. d958 4
  5726. d1014 3
  5727. d1053 1
  5728. a1053 1
  5729.     local($dir, $i, $current, $ok, @@tmp);
  5730. d1061 1
  5731. a1061 3
  5732.     @@tmp = split('/', $ENV{'PWD'});
  5733.     push(@@modules, pop(@@tmp));
  5734.     $current = 1;
  5735. d1083 3
  5736. a1085 8
  5737.     if (!$current) {
  5738.         if (!&chdir($i)) {
  5739.         printf("Can't chdir to $i: $!\n");
  5740.         return 1;
  5741.         }
  5742.         $path = $i;
  5743.     } else {
  5744.         $path = ".";
  5745. d1087 1
  5746. d1092 1
  5747. a1092 3
  5748.     if (!$current) {
  5749.         &chdir($dir) || die("Can't chdir to $dir: $!\n");
  5750.     }
  5751. d1106 3
  5752. a1108 8
  5753.     if (!$current) {
  5754.         if (!&chdir($i)) {
  5755.         printf("Can't chdir to $i: $!\n");
  5756.         return 1;
  5757.         }
  5758.         $path = $i;
  5759.     } else {
  5760.         $path = ".";
  5761. d1110 1
  5762. d1118 63
  5763. d1186 10
  5764. d1210 1
  5765. a1210 1
  5766.     &Opt_PrintUsage(@@options);
  5767. a1214 1
  5768. @@cvsCmds = ("diff", "add", "remove", "join", "patch", "tag");
  5769. d1237 3
  5770. a1239 1
  5771. } elsif (grep("$command eq $_", @@cvsCmds)) {
  5772. d1244 1
  5773. a1244 1
  5774.     &Opt_PrintUsage(@@options);
  5775. @
  5776.  
  5777.  
  5778. 1.1
  5779. log
  5780. @Initial revision
  5781. @
  5782. text
  5783. @d26 1
  5784. a26 1
  5785. $linkFile = "SCVS.links";
  5786. d29 1
  5787. a29 1
  5788. $infoFile = "SCVS.info";
  5789. d116 2
  5790. a117 1
  5791.     local($add) = 0;
  5792. d132 2
  5793. a133 6
  5794.     if (! -e "$linkFile") {
  5795.         $add = 1;
  5796.     } else {
  5797.         $add = 0;
  5798.     }
  5799.     printf(STDERR "Add = 1 in %s\n", $ENV{'PWD'}) if ($debug);
  5800. d143 7
  5801. a149 1
  5802.         if (open(PACK, ">$linkFile") == 0) {
  5803. d163 5
  5804. a167 2
  5805.         if ($add && (-e "CVS.adm")) {
  5806.         system("cvs -d $cvsroot add -m\"scvs links\" $linkFile");
  5807. d220 1
  5808. a220 1
  5809.     if (open(UNPACK, "$linkFile")) {
  5810. d317 1
  5811. a317 1
  5812.     local($getobjs) = 0; 
  5813. d320 4
  5814. a323 3
  5815.     "l", $OPT_FALSE, *recurse, "Don't recurse",
  5816.     "F", $OPT_FALSE, *force, "Don't force tags to match",
  5817.     "P", $OPT_FALSE, *prune, "Don't prune empty directories"
  5818. d325 1
  5819. a325 1
  5820.  
  5821. a333 2
  5822.     next if (/^-F/);
  5823.     next if (/^-P/);
  5824. d340 4
  5825. a349 5
  5826.     if (defined(@@args)) {
  5827.     $buffer .= " " . join(' ', @@args);
  5828.     } else {
  5829.     $getobjs = 1;
  5830.     }
  5831. d365 1
  5832. a365 1
  5833.     # Store the "cvs co" arguments in SCVS.info.
  5834. d367 12
  5835. a378 1
  5836.     open(CO, ">$i/$infoFile") || die("Can't open $i/$infoFile: $!\n");
  5837. d399 1
  5838. d484 2
  5839. d489 85
  5840. a573 9
  5841.     @@files = <$objdir/$path/*.o>;
  5842.     if (defined(@@files)) {
  5843.     local($quiet) = $verbose ? " " : "-q";
  5844.     $files = join(' ', @@files);
  5845.     printf(STDERR "Files: $files\n") if ($debug);
  5846.     system("update $quiet $files .");
  5847.     if ($?) {
  5848.         printf("Update failed: $?\n");
  5849.         return 1;
  5850. d696 1
  5851. a696 1
  5852.     if (open(UP, "$infoFile")) {
  5853. d714 1
  5854. a714 1
  5855.         if (open(UP, "$infoFile")) {
  5856. d758 1
  5857. a758 1
  5858.     if (! -e "CVS.adm") {
  5859. d859 2
  5860. d1153 4
  5861. d1187 2
  5862. @
  5863.